diff options
author | Karl Berry <karl@freefriends.org> | 2015-12-13 23:42:37 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-12-13 23:42:37 +0000 |
commit | 7937119a4012996251798f6a286ea904a05749f2 (patch) | |
tree | 7743f51a2906c0f0c9685f681e2a36646751290f /Master | |
parent | 3807f54388c3f5abc707c05be526c6c9c0c04623 (diff) |
luaotfload (13dec15)
git-svn-id: svn://tug.org/texlive/trunk@39093 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf | bin | 60168 -> 59751 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf | bin | 194494 -> 193975 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf | bin | 44933 -> 44933 bytes | |||
-rwxr-xr-x | Master/texmf-dist/scripts/luaotfload/mkimport | 253 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/luaotfload/mkstatus | 33 | ||||
-rw-r--r-- | Master/texmf-dist/source/luatex/luaotfload/Makefile | 6 | ||||
-rw-r--r-- | Master/texmf-dist/source/luatex/luaotfload/filegraph.dot | 10 | ||||
-rw-r--r-- | Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex | 27 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/luaotfload/fontloader-2015-12-12.lua (renamed from Master/texmf-dist/tex/luatex/luaotfload/fontloader-2015-12-09.lua) | 3406 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/luaotfload/luaotfload-package.lua | 99 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua | 14 |
11 files changed, 2557 insertions, 1291 deletions
diff --git a/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf b/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf Binary files differindex d795f78cb29..fcf20f6a705 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf +++ b/Master/texmf-dist/doc/luatex/luaotfload/filegraph.pdf diff --git a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf Binary files differindex ee17939d22c..61781c8ea81 100644 --- a/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf +++ b/Master/texmf-dist/doc/luatex/luaotfload/luaotfload.pdf diff --git a/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf b/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf Binary files differindex 8358d301ab9..031a1f3ab97 100644 --- a/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf +++ b/Master/texmf-dist/doc/man/man1/luaotfload-tool.man1.pdf diff --git a/Master/texmf-dist/scripts/luaotfload/mkimport b/Master/texmf-dist/scripts/luaotfload/mkimport index abe1608a60f..b3c71fedf24 100755 --- a/Master/texmf-dist/scripts/luaotfload/mkimport +++ b/Master/texmf-dist/scripts/luaotfload/mkimport @@ -30,10 +30,16 @@ local md5 = require "md5" local os = require "os" require "lualibs" +require "util-mrg" + +assert (utilities and utilities.merger and utilities.merger.compact + and type (utilities.merger.compact) == "function", + "Whoa, util-mrg.lua is not accessible! How do you expect this to work‽") local filedirname = file.dirname local fileiswritable = file.is_writable local ioloaddata = io.loaddata +local iosavedata = io.savedata local iopopen = io.popen local iowrite = io.write local lfschdir = lfs.chdir @@ -90,8 +96,6 @@ local prefixes = { --doc]]-- -local loader_merge_name = "luaotfload-package.lua" -local loader_output_name = "luaotfload-package-merged.lua" local loader_target_name = "fontloader-%s.lua" local loader_orig_dir = "/src/fontloader/" local loader_target_dir = "/build/" @@ -245,6 +249,107 @@ local imports = { }, --[[ [context] ]] } --[[ [imports] ]] +local package = { + + optional = { --- components not included in the default package + +--- The original initialization sequence by Hans Hagen, see the file +--- luatex-fonts.lua for details: +--- +--- [01] l-lua.lua +--- [02] l-lpeg.lua +--- [03] l-function.lua +--- [04] l-string.lua +--- [05] l-table.lua +--- [06] l-io.lua +--- [07] l-file.lua +--- [08] l-boolean.lua +--- [09] l-math.lua +--- [10] util-str.lua +--- [11] luatex-basics-gen.lua +--- [12] data-con.lua +--- [13] luatex-basics-nod.lua +--- [14] font-ini.lua +--- [15] font-con.lua +--- [16] luatex-fonts-enc.lua +--- [17] font-cid.lua +--- [18] font-map.lua +--- [19] luatex-fonts-syn.lua +--- [20] font-tfm.lua +--- [21] font-afm.lua +--- [22] font-afk.lua +--- [23] luatex-fonts-tfm.lua +--- [24] font-oti.lua +--- [25] font-otf.lua +--- [26] font-otb.lua +--- [27] luatex-fonts-inj.lua +--- [28] luatex-fonts-ota.lua +--- [29] luatex-fonts-otn.lua +--- [30] font-otp.lua +--- [31] luatex-fonts-lua.lua +--- [32] font-def.lua +--- [33] luatex-fonts-def.lua +--- [34] luatex-fonts-ext.lua +--- [35] luatex-fonts-cbk.lua +--- +--- Of these, nos. 01--10 are provided by the Lualibs. Keeping them +--- around in the Luaotfload fontloader is therefore unnecessary. +--- Packaging needs to account for this difference. + + "l-lua", + "l-lpeg", + "l-function", + "l-string", + "l-table", + "l-io", + "l-file", + "l-boolean", + "l-math", + "util-str", + +--- Another file containing auxiliary definitions must be present +--- prior to initialization of the configuration. + + "luatex-basics-gen", + + }, --[[ [package.optional] ]] + +--- The files below constitute the “fontloader proper”. Some of the +--- functionality like file resolvers is overloaded later by +--- Luaotfload. Consequently, the resulting package is pretty +--- bare-bones and not usable independently. + + required = { + + "data-con", + "basics-nod", + "font-ini", + "font-con", + "fonts-enc", + "font-cid", + "font-map", + "fonts-syn", + "font-tfm", + "font-afm", + "font-afk", + "fonts-tfm", + "font-oti", + "font-otf", + "font-otb", + "fonts-inj", + "fonts-ota", + "fonts-otn", + "font-otp", + "fonts-lua", + "font-def", + "fonts-def", + "fonts-ext", + "fonts-cbk", + + }, --[[ [package.required] ]] + +} --[[ [package] ]] + local hash_file = function (fname) if not lfsisfile (fname) then die ("cannot find %s.", fname) @@ -663,10 +768,8 @@ local build_paths = function (argv) local orig_dir = lfscurrentdir () local base_dir = orig_dir .. loader_orig_dir - local target_name = orig_dir .. loader_target_dir - .. stringformat (loader_target_name, os.date ("%F")) - local merge_name = base_dir .. loader_merge_name - local output_name = base_dir .. loader_output_name + local loader_name = stringformat (loader_target_name, os.date ("%F")) + local target_name = orig_dir .. loader_target_dir .. loader_name if #argv >= 2 then local fname = argv[2] @@ -676,8 +779,7 @@ local build_paths = function (argv) argv[2]) end base_dir = dir - merge_name = fname - output_name = dir .. loader_output_name + target_name = fname end if #argv == 3 then @@ -696,28 +798,93 @@ local build_paths = function (argv) base_dir = base_dir, merge_name = merge_name, target_name = target_name, - output_name = output_name, + loader_name = loader_name, } return ret end ---[[doc-- +local luaotfload_header = [==[ +--[[info----------------------------------------------------------------------- + Luaotfload fontloader package + build %s by %s@%s +------------------------------------------------------------------------------- - Packaging works as follows: + © %s PRAGMA ADE / ConTeXt Development Team - * Files are looked up the usual way, allowing us to override the - distribution-supplied scripts with our own alternatives in the - local path. + The code in this file is provided under the GPL v2.0 license. See the + file COPYING in the Luaotfload repository for details. - * The merged package is written to the same directory as the - packaging script (not ``$PWD``). + Report bugs to github.com/lualatex/luaotfload - There is some room for improvements: Instead of reading a file with - fixed content from disk, the merge script could be composed - on-the-fly from a list of files and then written to memory (not sure - though if we can access shm_open or memfd and the likes from Lua). + This file has been assembled from components taken from Context. See + the Luaotfload documentation for details: ---doc]]-- + $ texdoc luaotfload + $ man 1 luaotfload-tool + $ man 5 luaotfload.conf + + Included files: + +%s + +--info]]----------------------------------------------------------------------- + +]==] + +local make_header = function (files) + local filelist = { } + for i = 1, #files do + local f = files[i] + local _void, ourname = derive_ourname (f, kind_merged) + filelist [#filelist + 1] = stringformat (" · %s", ourname) + end + return stringformat (luaotfload_header, + os.date "%F %T", + os.getenv "USER" or "anon", + os.getenv "HOSTNAME" or "void", + os.date "%Y", + table.concat (filelist, "\n")) +end + + +local scope_start = "\ndo --- [luaotfload, %s scope for “%s” %s] ---\n\n" +local scope_stop = "\nend --- [luaotfload, %s scope for “%s”] ---\n\n" +local luaotfload_modeline = "\n--- vim:ft=lua:sw=2:ts=8:et:tw=79\n" + +local assemble_fontloader = function (tgt, dst) + status ("packaging fontloader as “%s”.", emphasis (tgt)) + local required = package.required + local compact = utilities.merger.compact + local sequence = { [1] = make_header (required) } + for i = 1, #required do + local cur = required [i] + local subdir, ourname = derive_ourname (cur, kind_merged) + local ourpath = file.join (fontloader_subdir, subdir, ourname) + local data = ioloaddata (ourpath) + if not data then + bad ("file “%s” cannot be loaded from “%s”", ourname, ourpath) + return false + end + sequence[#sequence + 1] = stringformat (scope_start, tgt, cur, md5sumhexa (data)) + sequence[#sequence + 1] = compact (data) + sequence[#sequence + 1] = stringformat (scope_stop , tgt, cur) + end + sequence[#sequence + 1] = luaotfload_modeline + local raw = table.concat (sequence) + local _void, chunk, err = pcall (loadstring, raw) + print(_void, chunk) + if chunk == nil then + bad ("packaging result not well-formed") + bad ("error message: “%s”", err) + bad ("dumping to fontloader-junk.lua") + iosavedata ("fontloader-junk.lua", raw) + return false + end + iosavedata (dst, raw) + status ("amalgamated %d files, written to “%s”.", + #required, dst) + return dst +end local package = function (argv) local t0 = osgettimeofday () @@ -725,21 +892,18 @@ local package = function (argv) status ("assuming fontloader source in %s", paths.base_dir) status ("reading merge instructions from %s", paths.merge_name) - status ("mtx-package result at %s", paths.output_name) status ("writing output to %s", paths.target_name) --- check preconditions if not lfsisdir (paths.base_dir) then die ("directory %s does not exist", emphasis (paths.base_dir )) end - if not lfsisfile (paths.merge_name) then die ("missing merge file at %s", emphasis (paths.merge_name )) end - if not fileiswritable (paths.output_name) then die ("cannot write to %s", emphasis (paths.output_name)) end if not fileiswritable (paths.target_name) then die ("cannot write to %s", emphasis (paths.target_name)) end ---- not lfschdir (paths.base_dir) then die ("failed to cd into %s", emphasis (paths.base_dir )) end - if lfsisfile (paths.output_name) then + if lfsisfile (paths.target_name) then status ("output file already exists at “%s”, unlinking", - paths.output_name) - local ret, err = os.remove (paths.output_name) + paths.target_name) + local ret, err = os.remove (paths.target_name) if ret == nil then if not lfschdir (paths.orig_dir) then status ("warning: failed to cd retour into %s", @@ -748,18 +912,11 @@ local package = function (argv) die ("failed to remove existing merge package") end end - --die ("missing merge file at %s", emphasis (paths.merge_name )) end - --- perform merge - local cmd = { "mtxrun", "--script", "package", "--merge", paths.merge_name } - local shl = tableconcat (cmd, " ") - - status ("invoking %s as “%s”", emphasis "mtx-package", shl) + local ret = assemble_fontloader (paths.loader_name, paths.target_name) - local fh = iopopen (shl, "r") - - if not fh then + if not ret then if not lfschdir (paths.orig_dir) then status ("warning: failed to cd retour into %s", emphasis (paths.orig_dir)) @@ -767,15 +924,6 @@ local package = function (argv) die ("merge failed; failed to invoke mtxrun") end - local junk = fh.read (fh, "*all") - if not junk then - status ("warning: received no output from mtxrun; this is strange") - end - - fh.close (fh) - - if debug then print (junk) end - --- clean up if not lfschdir (paths.orig_dir) then @@ -785,24 +933,13 @@ local package = function (argv) --- check postconditions - if not lfsisfile (paths.output_name) then - die ("merge failed; package not found at " .. paths.output_name) + if not lfsisfile (ret) then + die ("merge failed; package not found at “%s”", paths.output_name) end --- at this point we know that mtxrun was invoked correctly and the --- result file has been created - if lfsisfile (paths.target_name) then - status ("target file %s exists, overwriting", emphasis (paths.target_name)) - end - - local res, err = osrename (paths.output_name, paths.target_name) - - if res == nil then - die ("merge failed; failed to move package from %s to %s", - paths.output_name, paths.target_name) - end - status ("merge complete; operation finished in %.0f ms", (osgettimeofday() - t0) * 1000) status ("a fresh fontloader at %s is ready to roll", paths.target_name) diff --git a/Master/texmf-dist/scripts/luaotfload/mkstatus b/Master/texmf-dist/scripts/luaotfload/mkstatus index f27d57118cb..4b36a9dc8fc 100755 --- a/Master/texmf-dist/scripts/luaotfload/mkstatus +++ b/Master/texmf-dist/scripts/luaotfload/mkstatus @@ -12,6 +12,12 @@ -- This script generates a list of hashes that serves as the input -- for the file integrity check (option --diagnose). md5 is all we can -- assume in Luatex, so it’s really only a superficial test. +-- +-- Not that this file also incorporates the Git revision information. +-- Of this, only the actual commit hash is authoritative. The latest +-- tag is included for reference only. Besides that, it’s meaningless. +-- Do not rely on it: Two distinct versions of Luaotfload might very +-- well share the same tag. kpse.set_program_name "luatex" @@ -71,9 +77,6 @@ local names = { { scriptdir, "mkstatus", }, { scriptdir, "mktests", }, - --- merge script - { loaderdir, "luaotfload-package.lua", }, - --- fontloader runtimes { rtdir, "fontloader-basics-gen.lua", }, { rtdir, "fontloader-reference.lua", }, @@ -136,31 +139,41 @@ local die = function (...) os.exit (1) end -local gitcmd = "git log -1 \z +local logcmd = "git log -1 \z --format=\"return {\z %n revision = [[%H]],\z %n timestamp = [[%cd]],\z %n committer = [[%cn <%ce>]],\z %n}\" \z --date=iso" +local describecmd = "git describe --all" -local git_info = function () - --io.write (gitcmd) - --io.write "\n" - local chan = iopopen (gitcmd) +local readpipe = function (cmd) + local chan = iopopen (cmd) if not chan then die ("this script needs to be run inside \z the luaotfload git repository") end - local data = chan:read "*all" chan:close () + return data +end + +local git_info = function () + --io.write (logcmd) + --io.write "\n" + local desc = readpipe (describecmd) + if not desc then die "cannot parse git information" end + local desc = string.explode (string.fullstrip (desc), "/")[2] + local data = readpipe (logcmd) if data and type (data) == "string" and data ~= "" then data = load (data) if not data then die "cannot parse git information" end - return data () + data = data () + data.description = desc + return data end die "cannot read from pipe" end diff --git a/Master/texmf-dist/source/luatex/luaotfload/Makefile b/Master/texmf-dist/source/luatex/luaotfload/Makefile index f23c6b84c23..a131f3ace05 100644 --- a/Master/texmf-dist/source/luatex/luaotfload/Makefile +++ b/Master/texmf-dist/source/luatex/luaotfload/Makefile @@ -39,7 +39,6 @@ GRAPH = filegraph DOCSRC = $(addprefix $(DOCSRCDIR)/$(NAME), -main.tex -latex.tex) LOADERSRC = $(wildcard $(FONTLOADERSRCDIR)/*.lua) LOADERSRC += $(wildcard $(FONTLOADERSRCDIR)/*.tex) -LOADERSRC += $(PACKAGEDIR)/luaotfload-package.lua GRAPHSRC = $(DOCSRCDIR)/$(GRAPH).dot MANSRC = $(DOCSRCDIR)/$(TOOLNAME).rst $(DOCSRCDIR)/$(CONFNAME).rst @@ -99,8 +98,7 @@ DO_GLYPHS = $(LUA) $(GLYPHSCRIPT) > /dev/null DO_CHARS = $(LUA) $(CHARSCRIPT) > /dev/null DO_STATUS = $(LUA) $(STATUSSCRIPT) --fontloader=$(LOADER) >/dev/null DO_IMPORT = $(LUA) $(IMPORTSCRIPT) import >/dev/null -DO_PACKAGE = $(LUA) $(IMPORTSCRIPT) package \ - $(PACKAGEDIR)/luaotfload-package.lua $(LOADER) >/dev/null +DO_PACKAGE = $(LUA) $(IMPORTSCRIPT) package $(LOADER) >/dev/null define check-lua-files @echo validating syntax @@ -200,7 +198,7 @@ $(TDS_ZIP): $(DOCS) $(ALL_STATUS) check sign: $(CTAN_ZIPSIG) -.PHONY: install manifest clean mrproper show showtargets check import news +.PHONY: package install manifest clean mrproper show showtargets check import news install: @echo " ××××××××××××××××××××××××××××××××" diff --git a/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot b/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot index 9773ebd426f..de6082372f9 100644 --- a/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot +++ b/Master/texmf-dist/source/luatex/luaotfload/filegraph.dot @@ -54,7 +54,7 @@ strict digraph luaotfload_files { //looks weird with circo ... fontdbutil -> fontdbutil_diagnostics [label="--diagnose"] fontdbutil -> status [label="version information"] - luaotfload_package -> fontloader [label="merges", style=dashed] + mkimport -> fontloader [label="merges", style=dashed] merged_luatex_fonts -> characters [label="luaotfload-auxiliary.lua", ltail=cluster_merged] @@ -108,14 +108,6 @@ strict digraph luaotfload_files { //looks weird with circo ... style = "filled,rounded", penwidth=2] - luaotfload_package [label = "luaotfload-package.lua", - shape = rect, - width = "3.2cm", - height = "1.2cm", - color = "#01012222", - style = "filled,rounded", - penwidth=2] - fontdbutil_diagnostics [label = "luaotfload-diagnostics.lua", shape = rect, width = "3.2cm", diff --git a/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex b/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex index 967f5a2b346..ca1bc96e701 100644 --- a/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex +++ b/Master/texmf-dist/source/luatex/luaotfload/luaotfload-main.tex @@ -32,7 +32,7 @@ \beginfrontmatter \setdocumenttitle {The \identifier{luaotfload} package} - \setdocumentdate {2015/12/09 v2.6} + \setdocumentdate {2015/12/12 v2.6} \setdocumentauthor {Elie Roux · Khaled Hosny · Philipp Gesang\\ Home: \hyperlink {https://github.com/lualatex/luaotfload}\\ Support: \email {lualatex-dev@tug.org}} @@ -1076,8 +1076,8 @@ format. It integrates the font loader, written entirely in \LUA, as distributed in the \identifier{\LUATEX-Fonts} package. % -The original \LUA source files have been combined using the -\fileent{mtx-package} script into a single, self-contained blob. In +The original \LUA source files have been combined using the \CONTEXT +packaging library into a single, self-contained blob. In this form the font loader depends only on the \identifier{lualibs} package and requires only minor adaptions to integrate into \identifier{luaotfload}. @@ -1106,17 +1106,14 @@ See figure \ref{file-graph} on page \pageref{file-graph} for a graphical representation of the dependencies. % \label{package}% -Through the script \fileent{luaotfload-package.lua} the \CONTEXT -utility \fileent{mtx-package} is invoked to create the -\identifier{luaotfload} fontloader as a merged (amalgamated) source -file.\footnote{% - \fileent{mtx-package}, a \LUA source code merging tool developed by - Hans Hagen, is - \hyperlink [part of \CONTEXT]{https://bitbucket.org/phg/context-mirror/src/726a663be481042003566d4614266b940b5a0c91/scripts/context/lua/mtx-package.lua?at=beta} - and requires \fileent{mtxrun}. - Run - \inlinecode {mtxrun --script package --help} - to display further information. +Through the script \fileent{mkimport} a \CONTEXT library +is invoked to create the \identifier{luaotfload} fontloader as a merged +(amalgamated) source file.\footnote{% + In \CONTEXT, this facility can be accessed by means of a + \hyperlink[script]{https://bitbucket.org/phg/context-mirror/src/beta/scripts/context/lua/mtx-package.lua?at=beta} + which is integrated into \fileent{mtxrun} as a subcommand. + Run \inlinecode {mtxrun --script package --help} to display further + information. For the actual merging code see the file \fileent{util-mrg.lua} that is part of \CONTEXT. } @@ -1334,7 +1331,7 @@ The subcommand for importing takes the prefix of the desired \CONTEXT Whereas the command for packaging requires a path to the \emphasis{package description file} and the output name to be passed. \beginlisting -./scripts/mkimport package ./src/fontloader/luaotfload-package.lua fontloader-custom.lua +./scripts/mkimport package fontloader-custom.lua \endlisting From the toplevel makefile, the targets \inlinecode{import} and diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2015-12-09.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2015-12-12.lua index f4181c686c4..0eaf442ef32 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2015-12-09.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2015-12-12.lua @@ -1,8 +1,53 @@ --- merged file : /home/phg/src/latex-dev/luaotfload/src/fontloader/luaotfload-package-merged.lua --- parent file : /home/phg/src/latex-dev/luaotfload/src/fontloader/luaotfload-package.lua --- merge date : Wed Dec 9 23:19:38 2015 +--[[info----------------------------------------------------------------------- + Luaotfload fontloader package + build 2015-12-12 20:06:58 by phg@phlegethon +------------------------------------------------------------------------------- -do -- begin closure to overcome local limits and interference + © 2015 PRAGMA ADE / ConTeXt Development Team + + The code in this file is provided under the GPL v2.0 license. See the + file COPYING in the Luaotfload repository for details. + + Report bugs to github.com/lualatex/luaotfload + + This file has been assembled from components taken from Context. See + the Luaotfload documentation for details: + + $ texdoc luaotfload + $ man 1 luaotfload-tool + $ man 5 luaotfload.conf + + Included files: + + · fontloader-data-con.lua + · fontloader-basics-nod.lua + · fontloader-font-ini.lua + · fontloader-font-con.lua + · fontloader-fonts-enc.lua + · fontloader-font-cid.lua + · fontloader-font-map.lua + · fontloader-fonts-syn.lua + · fontloader-font-tfm.lua + · fontloader-font-afm.lua + · fontloader-font-afk.lua + · fontloader-fonts-tfm.lua + · fontloader-font-oti.lua + · fontloader-font-otf.lua + · fontloader-font-otb.lua + · fontloader-fonts-inj.lua + · fontloader-fonts-ota.lua + · fontloader-fonts-otn.lua + · fontloader-font-otp.lua + · fontloader-fonts-lua.lua + · fontloader-font-def.lua + · fontloader-fonts-def.lua + · fontloader-fonts-ext.lua + · fontloader-fonts-cbk.lua + +--info]]----------------------------------------------------------------------- + + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “data-con” 675f5a0af45ffb3e0d2e2ab5d6c2e47b] --- if not modules then modules={} end modules ['data-con']={ version=1.100, @@ -114,9 +159,10 @@ function containers.cleanname(name) return (gsub(lower(name),"[^%w\128-\255]+","-")) end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “data-con”] --- -do -- begin closure to overcome local limits and interference + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “basics-nod” d060e22b2afed6e7624f879b0e1a7d71] --- if not modules then modules={} end modules ['luatex-fonts-nod']={ version=1.001, @@ -158,6 +204,8 @@ local nodecodes={} for k,v in next,node.types () do nodecodes[string.gsub(v,"_" local whatcodes={} for k,v in next,node.whatsits() do whatcodes[string.gsub(v,"_","")]=k end local glyphcodes={ [0]="character","glyph","ligature","ghost","left","right" } local disccodes={ [0]="discretionary","explicit","automatic","regular","first","second" } +for i=0,#glyphcodes do glyphcodes[glyphcodes[i]]=i end +for i=0,#disccodes do disccodes [disccodes [i]]=i end nodes.nodecodes=nodecodes nodes.whatcodes=whatcodes nodes.whatsitcodes=whatcodes @@ -306,9 +354,10 @@ end nodes.setprop=nodes.setproperty nodes.getprop=nodes.getproperty -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “basics-nod”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-ini” 179f0a75cda26696c1b1cd6d7fe0d8ae] --- if not modules then modules={} end modules ['font-ini']={ version=1.001, @@ -332,9 +381,10 @@ fonts.definers={ methods={} } fonts.loggers={ register=function() end } fontloader.totable=fontloader.to_table -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-ini”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-con” 5ae91fc3b5bb8d22b2fba27258d49971] --- if not modules then modules={} end modules ['font-con']={ version=1.001, @@ -462,8 +512,8 @@ end constructors.setfactor() function constructors.scaled(scaledpoints,designsize) if scaledpoints<0 then + local factor=constructors.factor if designsize then - local factor=constructors.factor if designsize>factor then return (- scaledpoints/1000)*designsize else @@ -633,6 +683,7 @@ function constructors.scale(tfmdata,specification) local hdelta=delta local vdelta=delta target.designsize=parameters.designsize + target.units=units target.units_per_em=units local direction=properties.direction or tfmdata.direction or 0 target.direction=direction @@ -744,21 +795,28 @@ function constructors.scale(tfmdata,specification) target.nomath=true target.mathparameters=nil end - local italickey="italic" - local useitalics=true if hasmath then - autoitalicamount=false - elseif properties.textitalics then - italickey="italic_correction" - useitalics=false - if properties.delaytextitalics then + local mathitalics=properties.mathitalics + if mathitalics==false then + if trace_defining then + report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename) + end + hasitalics=false + autoitalicamount=false + end + else + local textitalics=properties.textitalics + if textitalics==false then + if trace_defining then + report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename) + end + hasitalics=false autoitalicamount=false end end if trace_defining then report_defining("defining tfm, name %a, fullname %a, filename %a, hscale %a, vscale %a, math %a, italics %a", - name,fullname,filename,hdelta,vdelta, - hasmath and "enabled" or "disabled",useitalics and "enabled" or "disabled") + name,fullname,filename,hdelta,vdelta,hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") end constructors.beforecopyingcharacters(target,tfmdata) local sharedkerns={} @@ -856,22 +914,6 @@ function constructors.scale(tfmdata,specification) chr.right_protruding=protrusionfactor*width*vr end end - if autoitalicamount then - local vi=description.italic - if not vi then - local vi=description.boundingbox[3]-description.width+autoitalicamount - if vi>0 then - chr[italickey]=vi*hdelta - end - elseif vi~=0 then - chr[italickey]=vi*hdelta - end - elseif hasitalics then - local vi=description.italic - if vi and vi~=0 then - chr[italickey]=vi*hdelta - end - end if hasmath then local vn=character.next if vn then @@ -909,7 +951,11 @@ function constructors.scale(tfmdata,specification) end end end - local va=character.top_accent + local vi=character.vert_italic + if vi and vi~=0 then + chr.vert_italic=vi*hdelta + end + local va=character.accent if va then chr.top_accent=vdelta*va end @@ -932,6 +978,27 @@ function constructors.scale(tfmdata,specification) chr.mathkern=kerns end end + if hasitalics then + local vi=character.italic + if vi and vi~=0 then + chr.italic=vi*hdelta + end + end + elseif autoitalicamount then + local vi=description.italic + if not vi then + local vi=description.boundingbox[3]-description.width+autoitalicamount + if vi>0 then + chr.italic=vi*hdelta + end + elseif vi~=0 then + chr.italic=vi*hdelta + end + elseif hasitalics then + local vi=character.italic + if vi and vi~=0 then + chr.italic=vi*hdelta + end end if haskerns then local vk=character.kerns @@ -994,6 +1061,7 @@ function constructors.scale(tfmdata,specification) end targetcharacters[unicode]=chr end + properties.setitalics=hasitalics constructors.aftercopyingcharacters(target,tfmdata) constructors.trytosharefont(target,tfmdata) return target @@ -1034,11 +1102,20 @@ function constructors.finalize(tfmdata) if not parameters.slantfactor then parameters.slantfactor=tfmdata.slant or 0 end - if not parameters.designsize then - parameters.designsize=tfmdata.designsize or (factors.pt*10) + local designsize=parameters.designsize + if designsize then + parameters.minsize=tfmdata.minsize or designsize + parameters.maxsize=tfmdata.maxsize or designsize + else + designsize=factors.pt*10 + parameters.designsize=designsize + parameters.minsize=designsize + parameters.maxsize=designsize end + parameters.minsize=tfmdata.minsize or parameters.designsize + parameters.maxsize=tfmdata.maxsize or parameters.designsize if not parameters.units then - parameters.units=tfmdata.units_per_em or 1000 + parameters.units=tfmdata.units or tfmdata.units_per_em or 1000 end if not tfmdata.descriptions then local descriptions={} @@ -1101,6 +1178,7 @@ function constructors.finalize(tfmdata) tfmdata.auto_protrude=nil tfmdata.extend=nil tfmdata.slant=nil + tfmdata.units=nil tfmdata.units_per_em=nil tfmdata.cache=nil properties.finalized=true @@ -1458,9 +1536,10 @@ function constructors.addcoreunicodes(unicodes) return unicodes end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-con”] --- -do -- begin closure to overcome local limits and interference + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-enc” b224fe179312d924ffaf8334cf5ef15b] --- if not modules then modules={} end modules ['luatex-font-enc']={ version=1.001, @@ -1488,9 +1567,10 @@ setmetatable(fonts.encodings.agl,{ __index=function(t,k) end end }) -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-enc”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-cid” 52421d1fdaa07ec4b1d936c6ff5079be] --- if not modules then modules={} end modules ['font-cid']={ version=1.001, @@ -1641,9 +1721,10 @@ function cid.getmap(specification) return found end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-cid”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-map” 60c9f3d4d80944ce9123c9cddc1e57e5] --- if not modules then modules={} end modules ['font-map']={ version=1.001, @@ -1665,24 +1746,13 @@ local fonts=fonts or {} local mappings=fonts.mappings or {} fonts.mappings=mappings local allocate=utilities.storage.allocate -local function loadlumtable(filename) - local lumname=file.replacesuffix(file.basename(filename),"lum") - local lumfile=resolvers.findfile(lumname,"map") or "" - if lumfile~="" and lfs.isfile(lumfile) then - if trace_loading or trace_mapping then - report_fonts("loading map table %a",lumfile) - end - lumunic=dofile(lumfile) - return lumunic,lumfile - end -end local hex=R("AF","09") -local hexfour=(hex*hex*hex*hex)/function(s) return tonumber(s,16) end -local hexsix=(hex*hex*hex*hex*hex*hex)/function(s) return tonumber(s,16) end +local hexfour=(hex*hex*hex^-2)/function(s) return tonumber(s,16) end +local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end local dec=(R("09")^1)/tonumber local period=P(".") -local unicode=P("uni")*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) -local ucode=P("u")*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) +local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) +local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) local index=P("index")*dec*Cc(false) local parser=unicode+ucode+index local parsers={} @@ -1757,7 +1827,6 @@ local function fromunicode16(str) return (tonumber(l,16))*0x400+tonumber(r,16)-0xDC00 end end -mappings.loadlumtable=loadlumtable mappings.makenameparser=makenameparser mappings.tounicode=tounicode mappings.tounicode16=tounicode16 @@ -1788,244 +1857,162 @@ for k,v in next,overloads do end end mappings.overloads=overloads -function mappings.addtounicode(data,filename) +function mappings.addtounicode(data,filename,checklookups) local resources=data.resources - local properties=data.properties - local descriptions=data.descriptions local unicodes=resources.unicodes - local lookuptypes=resources.lookuptypes if not unicodes then return end + local properties=data.properties + local descriptions=data.descriptions unicodes['space']=unicodes['space'] or 32 unicodes['hyphen']=unicodes['hyphen'] or 45 unicodes['zwj']=unicodes['zwj'] or 0x200D unicodes['zwnj']=unicodes['zwnj'] or 0x200C - local private=fonts.constructors.privateoffset - local unicodevector=fonts.encodings.agl.unicodes + local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 + local unicodevector=fonts.encodings.agl.unicodes or {} + local contextvector=fonts.encodings.agl.ctxcodes or {} local missing={} - local lumunic,uparser,oparser - local cidinfo,cidnames,cidcodes,usedmap - cidinfo=properties.cidinfo - usedmap=cidinfo and fonts.cid.getmap(cidinfo) + local nofmissing=0 + local oparser=nil + local cidnames=nil + local cidcodes=nil + local cidinfo=properties.cidinfo + local usedmap=cidinfo and fonts.cid.getmap(cidinfo) + local uparser=makenameparser() if usedmap then - oparser=usedmap and makenameparser(cidinfo.ordering) - cidnames=usedmap.names - cidcodes=usedmap.unicodes + oparser=usedmap and makenameparser(cidinfo.ordering) + cidnames=usedmap.names + cidcodes=usedmap.unicodes end - uparser=makenameparser() - local ns,nl=0,0 + local ns=0 + local nl=0 for unic,glyph in next,descriptions do - local index=glyph.index local name=glyph.name - local r=overloads[name] - if r then - glyph.unicode=r.unicode - elseif unic==-1 or unic>=private or (unic>=0xE000 and unic<=0xF8FF) or unic==0xFFFE or unic==0xFFFF then - local unicode=lumunic and lumunic[name] or unicodevector[name] - if unicode then - glyph.unicode=unicode - ns=ns+1 - end - if (not unicode) and usedmap then - local foundindex=lpegmatch(oparser,name) - if foundindex then - unicode=cidcodes[foundindex] - if unicode then - glyph.unicode=unicode - ns=ns+1 - else - local reference=cidnames[foundindex] - if reference then - local foundindex=lpegmatch(oparser,reference) - if foundindex then - unicode=cidcodes[foundindex] - if unicode then - glyph.unicode=unicode - ns=ns+1 - end - end - if not unicode or unicode=="" then - local foundcodes,multiple=lpegmatch(uparser,reference) - if foundcodes then - glyph.unicode=foundcodes - if multiple then - nl=nl+1 - unicode=true - else + if name then + local index=glyph.index + local r=overloads[name] + if r then + glyph.unicode=r.unicode + elseif not unic or unic==-1 or unic>=private or (unic>=0xE000 and unic<=0xF8FF) or unic==0xFFFE or unic==0xFFFF then + local unicode=unicodevector[name] or contextvector[name] + if unicode then + glyph.unicode=unicode + ns=ns+1 + end + if (not unicode) and usedmap then + local foundindex=lpegmatch(oparser,name) + if foundindex then + unicode=cidcodes[foundindex] + if unicode then + glyph.unicode=unicode + ns=ns+1 + else + local reference=cidnames[foundindex] + if reference then + local foundindex=lpegmatch(oparser,reference) + if foundindex then + unicode=cidcodes[foundindex] + if unicode then + glyph.unicode=unicode ns=ns+1 - unicode=foundcodes + end + end + if not unicode or unicode=="" then + local foundcodes,multiple=lpegmatch(uparser,reference) + if foundcodes then + glyph.unicode=foundcodes + if multiple then + nl=nl+1 + unicode=true + else + ns=ns+1 + unicode=foundcodes + end end end end end end end - end - if not unicode or unicode=="" then - local split=lpegmatch(namesplitter,name) - local nsplit=split and #split or 0 - local t,n={},0 - unicode=true - for l=1,nsplit do - local base=split[l] - local u=unicodes[base] or unicodevector[base] - if not u then - break - elseif type(u)=="table" then - if u[1]>=private then - unicode=false - break - end - n=n+1 - t[n]=u[1] - else - if u>=private then - unicode=false - break + if not unicode or unicode=="" then + local split=lpegmatch(namesplitter,name) + local nsplit=split and #split or 0 + if nsplit==0 then + elseif nsplit==1 then + local base=split[1] + local u=unicodes[base] or unicodevector[base] or contextvector[name] + if not u then + elseif type(u)=="table" then + if u[1]<private then + unicode=u + glyph.unicode=unicode + end + elseif u<private then + unicode=u + glyph.unicode=unicode end - n=n+1 - t[n]=u - end - end - if n==0 then - elseif n==1 then - glyph.unicode=t[1] - else - glyph.unicode=t - end - nl=nl+1 - end - if not unicode or unicode=="" then - local foundcodes,multiple=lpegmatch(uparser,name) - if foundcodes then - glyph.unicode=foundcodes - if multiple then - nl=nl+1 - unicode=true else - ns=ns+1 - unicode=foundcodes - end - end - end - local r=overloads[unicode] - if r then - unicode=r.unicode - glyph.unicode=unicode - end - if not unicode then - missing[name]=true - end - end - end - if next(missing) then - local guess={} - local function check(gname,code,unicode) - local description=descriptions[code] - local variant=description.name - if variant==gname then - return - end - local unic=unicodes[variant] - if unic==-1 or unic>=private or (unic>=0xE000 and unic<=0xF8FF) or unic==0xFFFE or unic==0xFFFF then - else - return - end - if descriptions[code].unicode then - return - end - local g=guess[variant] - if g then - g[gname]=unicode - else - guess[variant]={ [gname]=unicode } - end - end - for unicode,description in next,descriptions do - local slookups=description.slookups - if slookups then - local gname=description.name - for tag,data in next,slookups do - local lookuptype=lookuptypes[tag] - if lookuptype=="alternate" then - for i=1,#data do - check(gname,data[i],unicode) - end - elseif lookuptype=="substitution" then - check(gname,data,unicode) - end - end - end - local mlookups=description.mlookups - if mlookups then - local gname=description.name - for tag,list in next,mlookups do - local lookuptype=lookuptypes[tag] - if lookuptype=="alternate" then - for i=1,#list do - local data=list[i] - for i=1,#data do - check(gname,data[i],unicode) + local t,n={},0 + for l=1,nsplit do + local base=split[l] + local u=unicodes[base] or unicodevector[base] or contextvector[name] + if not u then + break + elseif type(u)=="table" then + if u[1]>=private then + break + end + n=n+1 + t[n]=u[1] + else + if u>=private then + break + end + n=n+1 + t[n]=u end end - elseif lookuptype=="substitution" then - for i=1,#list do - check(gname,list[i],unicode) + if n>0 then + if n==1 then + unicode=t[1] + else + unicode=t + end + glyph.unicode=unicode end end + nl=nl+1 end - end - end - local done=true - while done do - done=false - for k,v in next,guess do - if type(v)~="number" then - for kk,vv in next,v do - if vv==-1 or vv>=private or (vv>=0xE000 and vv<=0xF8FF) or vv==0xFFFE or vv==0xFFFF then - local uu=guess[kk] - if type(uu)=="number" then - guess[k]=uu - done=true - end + if not unicode or unicode=="" then + local foundcodes,multiple=lpegmatch(uparser,name) + if foundcodes then + glyph.unicode=foundcodes + if multiple then + nl=nl+1 + unicode=true else - guess[k]=vv - done=true + ns=ns+1 + unicode=foundcodes end end end - end - end - local orphans=0 - local guessed=0 - for k,v in next,guess do - if type(v)=="number" then - descriptions[unicodes[k]].unicode=descriptions[v].unicode or v - guessed=guessed+1 - else - local t=nil - local l=lower(k) - local u=unicodes[l] - if not u then - orphans=orphans+1 - elseif u==-1 or u>=private or (u>=0xE000 and u<=0xF8FF) or u==0xFFFE or u==0xFFFF then - local unicode=descriptions[u].unicode - if unicode then - descriptions[unicodes[k]].unicode=unicode - guessed=guessed+1 - else - orphans=orphans+1 - end - else - orphans=orphans+1 + local r=overloads[unicode] + if r then + unicode=r.unicode + glyph.unicode=unicode + end + if not unicode then + missing[unic]=true + nofmissing=nofmissing+1 end end - end - if trace_loading and orphans>0 or guessed>0 then - report_fonts("%s glyphs with no related unicode, %s guessed, %s orphans",guessed+orphans,guessed,orphans) + else end end + if type(checklookups)=="function" then + checklookups(data,missing,nofmissing) + end if trace_mapping then for unic,glyph in table.sortedhash(descriptions) do local name=glyph.name @@ -2051,9 +2038,10 @@ function mappings.addtounicode(data,filename) end end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-map”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-syn” 9729d0e49b770f78e88dab86739e0297] --- if not modules then modules={} end modules ['luatex-fonts-syn']={ version=1.001, @@ -2129,9 +2117,10 @@ function fonts.names.ignoredfile(filename) return false end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-syn”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-tfm” bbee5eddb11211fb0a8d993db678bf3c] --- if not modules then modules={} end modules ['font-tfm']={ version=1.001, @@ -2153,6 +2142,9 @@ local readers=fonts.readers local constructors=fonts.constructors local encodings=fonts.encodings local tfm=constructors.newhandler("tfm") +tfm.version=1.000 +tfm.maxnestingdepth=5 +tfm.maxnestingsize=65536*1024 local tfmfeatures=constructors.newfeatures("tfm") local registertfmfeature=tfmfeatures.register constructors.resolvevirtualtoo=false @@ -2165,9 +2157,11 @@ function tfm.setfeatures(tfmdata,features) return {} end end +local depth={} local function read_from_tfm(specification) local filename=specification.filename local size=specification.size + depth[filename]=(depth[filename] or 0)+1 if trace_defining then report_defining("loading tfm file %a at size %s",filename,size) end @@ -2211,6 +2205,25 @@ local function read_from_tfm(specification) end properties.virtualized=true tfmdata.fonts=vfdata.fonts + tfmdata.type="virtual" + local fontlist=vfdata.fonts + local name=file.nameonly(filename) + for i=1,#fontlist do + local n=fontlist[i].name + local s=fontlist[i].size + local d=depth[filename] + s=constructors.scaled(s,vfdata.designsize) + if d>tfm.maxnestingdepth then + report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) + fontlist[i]={ id=0 } + elseif (d>1) and (s>tfm.maxnestingsize) then + report_defining("virtual font %a exceeds size %s",n,s) + fontlist[i]={ id=0 } + else + local t,id=fonts.constructors.readanddefine(n,s) + fontlist[i]={ id=id } + end + end end end end @@ -2226,7 +2239,10 @@ local function read_from_tfm(specification) properties.haslogatures=true resources.unicodes={} resources.lookuptags={} + depth[filename]=depth[filename]-1 return tfmdata + else + depth[filename]=depth[filename]-1 end end local function check_tfm(specification,fullname) @@ -2259,9 +2275,10 @@ function readers.tfm(specification) return check_tfm(specification,fullname) end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-tfm”] --- -do -- begin closure to overcome local limits and interference + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-afm” ece4863414d6b38c2e577110c9b55bd3] --- if not modules then modules={} end modules ['font-afm']={ version=1.001, @@ -2339,7 +2356,7 @@ local keys={} function keys.FontName (data,line) data.metadata.fontname=strip (line) data.metadata.fullname=strip (line) end function keys.ItalicAngle (data,line) data.metadata.italicangle=tonumber (line) end -function keys.IsFixedPitch(data,line) data.metadata.isfixedpitch=toboolean(line,true) end +function keys.IsFixedPitch(data,line) data.metadata.monospaced=toboolean(line,true) end function keys.CharWidth (data,line) data.metadata.charwidth=tonumber (line) end function keys.XHeight (data,line) data.metadata.xheight=tonumber (line) end function keys.Descender (data,line) data.metadata.descender=tonumber (line) end @@ -2761,7 +2778,7 @@ local function copytotfm(data) local emdash=0x2014 local spacer="space" local spaceunits=500 - local monospaced=metadata.isfixedpitch + local monospaced=metadata.monospaced local charwidth=metadata.charwidth local italicangle=metadata.italicangle local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight @@ -3113,9 +3130,10 @@ function readers.pfb(specification,method) return readers.afm(specification,method) end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-afm”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-afk” b36a76ceb835f41f8c05b471000ddc14] --- if not modules then modules={} end modules ['font-afk']={ version=1.001, @@ -3282,9 +3300,10 @@ fonts.handlers.afm.helpdata={ } } -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-afk”] --- -do -- begin closure to overcome local limits and interference + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-tfm” 8fd3865240e4e87e99e0739abeda2322] --- if not modules then modules={} end modules ['luatex-fonts-tfm']={ version=1.001, @@ -3322,9 +3341,10 @@ function fonts.readers.tfm(specification) end end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-tfm”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-oti” 035a51b49029d7da48453ec5f1d65018] --- if not modules then modules={} end modules ['font-oti']={ version=1.001, @@ -3404,9 +3424,10 @@ registerotffeature { } } -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-oti”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-otf” b1a5f4340125198b1b0489ef903dd267] --- if not modules then modules={} end modules ['font-otf']={ version=1.001, @@ -3416,12 +3437,10 @@ if not modules then modules={} end modules ['font-otf']={ license="see context related readme files" } local utfbyte=utf.byte -local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip +local gmatch,gsub,find,match,lower,strip=string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip local type,next,tonumber,tostring=type,next,tonumber,tostring local abs=math.abs -local insert=table.insert -local lpegmatch=lpeg.match -local reversed,concat,remove,sortedkeys=table.reversed,table.concat,table.remove,table.sortedkeys +local reversed,concat,insert,remove,sortedkeys=table.reversed,table.concat,table.insert,table.remove,table.sortedkeys local ioflush=io.flush local fastcopy,tohash,derivetable=table.fastcopy,table.tohash,table.derive local formatters=string.formatters @@ -3435,6 +3454,7 @@ local stoptiming=statistics.stoptiming local elapsedtime=statistics.elapsedtime local findbinfile=resolvers.findbinfile local trace_private=false registertracker("otf.private",function(v) trace_private=v end) +local trace_subfonts=false registertracker("otf.subfonts",function(v) trace_subfonts=v end) local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end) local trace_features=false registertracker("otf.features",function(v) trace_features=v end) local trace_dynamics=false registertracker("otf.dynamics",function(v) trace_dynamics=v end) @@ -3447,7 +3467,7 @@ local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf otf.glists={ "gsub","gpos" } -otf.version=2.803 +otf.version=2.819 otf.cache=containers.define("fonts","otf",otf.version,true) local hashes=fonts.hashes local definers=fonts.definers @@ -3624,10 +3644,10 @@ local ordered_enhancers={ "reorganize subtables", "check glyphs", "check metadata", - "check extra features", "prepare tounicode", "check encoding", "add duplicates", + "expand lookups", "cleanup tables", "compact lookups", "purge names", @@ -3764,6 +3784,7 @@ function otf.load(filename,sub,featurefile) end end if reload then + starttiming("fontloader") report_otf("loading %a, hash %a",filename,hash) local fontdata,messages if sub then @@ -3797,6 +3818,7 @@ function otf.load(filename,sub,featurefile) data={ size=size, time=time, + subfont=sub, format=otf_format(filename), featuredata=featurefiles, resources={ @@ -3824,7 +3846,6 @@ function otf.load(filename,sub,featurefile) tounicodetable=Ct(splitter), }, } - starttiming(data) report_otf("file size: %s",size) enhancers.apply(data,filename,fontdata) local packtime={} @@ -3841,10 +3862,10 @@ function otf.load(filename,sub,featurefile) if cleanup>1 then collectgarbage("collect") end - stoptiming(data) + stoptiming("fontloader") if elapsedtime then - report_otf("preprocessing and caching time %s, packtime %s", - elapsedtime(data),packdata and elapsedtime(packtime) or 0) + report_otf("loading, optimizing, packing and caching time %s, pack time %s", + elapsedtime("fontloader"),packdata and elapsedtime(packtime) or 0) end close_font(fontdata) if cleanup>3 then @@ -3855,6 +3876,7 @@ function otf.load(filename,sub,featurefile) collectgarbage("collect") end else + stoptiming("fontloader") data=nil report_otf("loading failed due to read error") end @@ -3896,6 +3918,7 @@ function otf.load(filename,sub,featurefile) applyruntimefixes(filename,data) end enhance("add dimensions",data,filename,nil,false) +enhance("check extra features",data,filename) if trace_sequences then showfeatureorder(data,filename) end @@ -3980,6 +4003,7 @@ local function somecopy(old) end end actions["prepare glyphs"]=function(data,filename,raw) + local tableversion=tonumber(raw.table_version) or 0 local rawglyphs=raw.glyphs local rawsubfonts=raw.subfonts local rawcidinfo=raw.cidinfo @@ -4000,65 +4024,114 @@ actions["prepare glyphs"]=function(data,filename,raw) local cidmap=fonts.cid.getmap(rawcidinfo) if cidmap then rawcidinfo.usedname=cidmap.usedname - local nofnames,nofunicodes=0,0 - local cidunicodes,cidnames=cidmap.unicodes,cidmap.names + local nofnames=0 + local nofunicodes=0 + local cidunicodes=cidmap.unicodes + local cidnames=cidmap.names + local cidtotal=0 + local unique=trace_subfonts and {} for cidindex=1,#rawsubfonts do local subfont=rawsubfonts[cidindex] local cidglyphs=subfont.glyphs if includesubfonts then metadata.subfonts[cidindex]=somecopy(subfont) end - for index=0,subfont.glyphcnt-1 do - local glyph=cidglyphs[index] - if glyph then - local unicode=glyph.unicode - if unicode>=0x00E000 and unicode<=0x00F8FF then - unicode=-1 - elseif unicode>=0x0F0000 and unicode<=0x0FFFFD then - unicode=-1 - elseif unicode>=0x100000 and unicode<=0x10FFFD then - unicode=-1 - end - local name=glyph.name or cidnames[index] - if not unicode or unicode==-1 then - unicode=cidunicodes[index] - end - if unicode and descriptions[unicode] then - if trace_private then - report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode) + local cidcnt,cidmin,cidmax + if tableversion>0.3 then + cidcnt=subfont.glyphcnt + cidmin=subfont.glyphmin + cidmax=subfont.glyphmax + else + cidcnt=subfont.glyphcnt + cidmin=0 + cidmax=cidcnt-1 + end + if trace_subfonts then + local cidtot=cidmax-cidmin+1 + cidtotal=cidtotal+cidtot + report_otf("subfont: %i, min: %i, max: %i, cnt: %i, n: %i",cidindex,cidmin,cidmax,cidtot,cidcnt) + end + if cidcnt>0 then + for cidslot=cidmin,cidmax do + local glyph=cidglyphs[cidslot] + if glyph then + local index=tableversion>0.3 and glyph.orig_pos or cidslot + if trace_subfonts then + unique[index]=true end - unicode=-1 - end - if not unicode or unicode==-1 then - if not name then - name=format("u%06X.ctx",private) + local unicode=glyph.unicode + if unicode>=0x00E000 and unicode<=0x00F8FF then + unicode=-1 + elseif unicode>=0x0F0000 and unicode<=0x0FFFFD then + unicode=-1 + elseif unicode>=0x100000 and unicode<=0x10FFFD then + unicode=-1 end - unicode=private - unicodes[name]=private - if trace_private then - report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) + local name=glyph.name or cidnames[index] + if not unicode or unicode==-1 then + unicode=cidunicodes[index] end - private=private+1 - nofnames=nofnames+1 - else - if not name then - name=format("u%06X.ctx",unicode) + if unicode and descriptions[unicode] then + if trace_private then + report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode) + end + unicode=-1 end - unicodes[name]=unicode - nofunicodes=nofunicodes+1 - end - indices[index]=unicode - local description={ - boundingbox=glyph.boundingbox, - name=name or "unknown", - cidindex=cidindex, - index=index, - glyph=glyph, - } - descriptions[unicode]=description + if not unicode or unicode==-1 then + if not name then + name=formatters["u%06X.ctx"](private) + end + unicode=private + unicodes[name]=private + if trace_private then + report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) + end + private=private+1 + nofnames=nofnames+1 + else + if not name then + name=formatters["u%06X.ctx"](unicode) + end + unicodes[name]=unicode + nofunicodes=nofunicodes+1 + end + indices[index]=unicode + local description={ + boundingbox=glyph.boundingbox, + name=name or "unknown", + cidindex=cidindex, + index=cidslot, + glyph=glyph, + } + descriptions[unicode]=description + local altuni=glyph.altuni + if altuni then + for i=1,#altuni do + local a=altuni[i] + local u=a.unicode + if u~=unicode then + local v=a.variant + if v then + local vv=variants[v] + if vv then + vv[u]=unicode + else + vv={ [u]=unicode } + variants[v]=vv + end + end + end + end + end + end end + else + report_otf("potential problem: no glyphs found in subfont %i",cidindex) end end + if trace_subfonts then + report_otf("nofglyphs: %i, unique: %i",cidtotal,table.count(unique)) + end if trace_loading then report_otf("cid font remapped, %s unicode points, %s symbolic names, %s glyphs",nofunicodes,nofnames,nofunicodes+nofnames) end @@ -4069,68 +4142,77 @@ actions["prepare glyphs"]=function(data,filename,raw) report_otf("font %a has no glyphs",filename) end else - for index=0,raw.glyphcnt-1 do - local glyph=rawglyphs[index] - if glyph then - local unicode=glyph.unicode - local name=glyph.name - if not unicode or unicode==-1 then - unicode=private - unicodes[name]=private - if trace_private then - report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) - end - private=private+1 - else - if unicode>criterium then - local taken=descriptions[unicode] - if taken then - if unicode>=private then - private=unicode+1 + local cnt=raw.glyphcnt or 0 + local min=tableversion>0.3 and raw.glyphmin or 0 + local max=tableversion>0.3 and raw.glyphmax or (raw.glyphcnt-1) + if cnt>0 then + for index=min,max do + local glyph=rawglyphs[index] + if glyph then + local unicode=glyph.unicode + local name=glyph.name + if not unicode or unicode==-1 then + unicode=private + unicodes[name]=private + if trace_private then + report_otf("glyph %a at index %H is moved to private unicode slot %U",name,index,private) + end + private=private+1 + else + if unicode>criterium then + local taken=descriptions[unicode] + if taken then + if unicode>=private then + private=unicode+1 + else + private=private+1 + end + descriptions[private]=taken + unicodes[taken.name]=private + indices[taken.index]=private + if trace_private then + report_otf("slot %U is moved to %U due to private in font",unicode) + end else - private=private+1 - end - descriptions[private]=taken - unicodes[taken.name]=private - indices[taken.index]=private - if trace_private then - report_otf("slot %U is moved to %U due to private in font",unicode) - end - else - if unicode>=private then - private=unicode+1 + if unicode>=private then + private=unicode+1 + end end end + unicodes[name]=unicode end - unicodes[name]=unicode - end - indices[index]=unicode - descriptions[unicode]={ - boundingbox=glyph.boundingbox, - name=name, - index=index, - glyph=glyph, - } - local altuni=glyph.altuni - if altuni then - for i=1,#altuni do - local a=altuni[i] - local u=a.unicode - local v=a.variant - if v then - local vv=variants[v] - if vv then - vv[u]=unicode - else - vv={ [u]=unicode } - variants[v]=vv + indices[index]=unicode + descriptions[unicode]={ + boundingbox=glyph.boundingbox, + name=name, + index=index, + glyph=glyph, + } + local altuni=glyph.altuni + if altuni then + for i=1,#altuni do + local a=altuni[i] + local u=a.unicode + if u~=unicode then + local v=a.variant + if v then + local vv=variants[v] + if vv then + vv[u]=unicode + else + vv={ [u]=unicode } + variants[v]=vv + end + end end end end + else + report_otf("potential problem: glyph %U is used but empty",index) end - else - report_otf("potential problem: glyph %U is used but empty",index) end + else + report_otf("potential problem: no glyphs found") end end resources.private=private @@ -4226,7 +4308,7 @@ actions["add duplicates"]=function(data,filename,raw) end if u>0 then local duplicate=table.copy(description) - duplicate.comment=format("copy of U+%05X",unicode) + duplicate.comment=formatters["copy of %U"](unicode) descriptions[u]=duplicate if trace_loading then report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n) @@ -4247,7 +4329,7 @@ actions["analyze glyphs"]=function(data,filename,raw) local marks={} for unicode,description in next,descriptions do local glyph=description.glyph - local italic=glyph.italic_correction + local italic=glyph.italic_correction if not italic then elseif italic==0 then else @@ -4308,7 +4390,8 @@ end actions["reorganize features"]=function(data,filename,raw) local features={} data.resources.features=features - for k,what in next,otf.glists do + for k=1,#otf.glists do + local what=otf.glists[k] local dw=raw[what] if dw then local f={} @@ -4390,8 +4473,9 @@ actions["reorganize subtables"]=function(data,filename,raw) local lookups={} local chainedfeatures={} resources.sequences=sequences - resources.lookups=lookups - for _,what in next,otf.glists do + resources.lookups=lookups + for k=1,#otf.glists do + local what=otf.glists[k] local dw=raw[what] if dw then for k=1,#dw do @@ -4565,12 +4649,15 @@ local function r_uncover(splitter,cache,cover,replacements) end actions["reorganize lookups"]=function(data,filename,raw) if data.lookups then - local splitter=data.helpers.tounicodetable + local helpers=data.helpers + local duplicates=data.resources.duplicates + local splitter=helpers.tounicodetable local t_u_cache={} local s_u_cache=t_u_cache local t_h_cache={} local s_h_cache=t_h_cache local r_u_cache={} + helpers.matchcache=t_h_cache for _,lookup in next,data.lookups do local rules=lookup.rules if rules then @@ -4716,6 +4803,44 @@ actions["reorganize lookups"]=function(data,filename,raw) end end end +actions["expand lookups"]=function(data,filename,raw) + if data.lookups then + local cache=data.helpers.matchcache + if cache then + local duplicates=data.resources.duplicates + for key,hash in next,cache do + local done=nil + for key in next,hash do + local unicode=duplicates[key] + if not unicode then + elseif type(unicode)=="table" then + for i=1,#unicode do + local u=unicode[i] + if hash[u] then + elseif done then + done[u]=key + else + done={ [u]=key } + end + end + else + if hash[unicode] then + elseif done then + done[unicode]=key + else + done={ [unicode]=key } + end + end + end + if done then + for u in next,done do + hash[u]=true + end + end + end + end + end +end local function check_variants(unicode,the_variants,splitter,unicodes) local variants=the_variants.variants if variants then @@ -4756,11 +4881,11 @@ local function check_variants(unicode,the_variants,splitter,unicodes) parts=nil end end - local italic_correction=the_variants.italic_correction - if italic_correction and italic_correction==0 then - italic_correction=nil + local italic=the_variants.italic + if italic and italic==0 then + italic=nil end - return variants,parts,italic_correction + return variants,parts,italic end actions["analyze math"]=function(data,filename,raw) if raw.math then @@ -4770,13 +4895,14 @@ actions["analyze math"]=function(data,filename,raw) for unicode,description in next,data.descriptions do local glyph=description.glyph local mathkerns=glyph.mathkern - local horiz_variants=glyph.horiz_variants - local vert_variants=glyph.vert_variants - local top_accent=glyph.top_accent - if mathkerns or horiz_variants or vert_variants or top_accent then + local hvariants=glyph.horiz_variants + local vvariants=glyph.vert_variants + local accent=glyph.top_accent + local italic=glyph.italic_correction + if mathkerns or hvariants or vvariants or accent or italic then local math={} - if top_accent then - math.top_accent=top_accent + if accent then + math.accent=accent end if mathkerns then for k,v in next,mathkerns do @@ -4792,15 +4918,14 @@ actions["analyze math"]=function(data,filename,raw) end math.kerns=mathkerns end - if horiz_variants then - math.horiz_variants,math.horiz_parts,math.horiz_italic_correction=check_variants(unicode,horiz_variants,splitter,unicodes) + if hvariants then + math.hvariants,math.hparts,math.hitalic=check_variants(unicode,hvariants,splitter,unicodes) end - if vert_variants then - math.vert_variants,math.vert_parts,math.vert_italic_correction=check_variants(unicode,vert_variants,splitter,unicodes) + if vvariants then + math.vvariants,math.vparts,math.vitalic=check_variants(unicode,vvariants,splitter,unicodes) end - local italic_correction=description.italic - if italic_correction and italic_correction~=0 then - math.italic_correction=italic_correction + if italic and italic~=0 then + math.italic=italic end description.math=math end @@ -4868,7 +4993,7 @@ actions["merge kern classes"]=function(data,filename,raw) local subtable=subtables[s] local kernclass=subtable.kernclass local lookup=subtable.lookup or subtable.name - if kernclass then + if kernclass then if #kernclass>0 then kernclass=kernclass[1] lookup=type(kernclass.lookup)=="string" and kernclass.lookup or lookup @@ -4893,14 +5018,16 @@ actions["merge kern classes"]=function(data,filename,raw) if splt then local extrakerns={} local baseoffset=(fk-1)*maxseconds - for sk=2,maxseconds do + for sk=2,maxseconds do local sv=seconds[sk] - local splt=split[sv] - if splt then - local offset=offsets[baseoffset+sk] - if offset then - for i=1,#splt do - extrakerns[splt[i]]=offset + if sv then + local splt=split[sv] + if splt then + local offset=offsets[baseoffset+sk] + if offset then + for i=1,#splt do + extrakerns[splt[i]]=offset + end end end end @@ -4957,7 +5084,7 @@ actions["merge kern classes"]=function(data,filename,raw) report_otf("%s kern overloads ignored",ignored) end if blocked>0 then - report_otf("%s succesive kerns blocked",blocked) + report_otf("%s successive kerns blocked",blocked) end end end @@ -4986,16 +5113,18 @@ actions["check metadata"]=function(data,filename,raw) ttftables[i].data="deleted" end end + local names=raw.names if metadata.validation_state and table.contains(metadata.validation_state,"bad_ps_fontname") then local function valid(what) - local names=raw.names - for i=1,#names do - local list=names[i] - local names=list.names - if names then - local name=names[what] - if name and valid_ps_name(name) then - return name + if names then + for i=1,#names do + local list=names[i] + local names=list.names + if names then + local name=names[what] + if name and valid_ps_name(name) then + return name + end end end end @@ -5018,6 +5147,28 @@ actions["check metadata"]=function(data,filename,raw) check("fontname") check("fullname") end + if names then + local psname=metadata.psname + if not psname or psname=="" then + for i=1,#names do + local name=names[i] + if lower(name.lang)=="english (us)" then + local specification=name.names + if specification then + local postscriptname=specification.postscriptname + if postscriptname then + psname=postscriptname + end + end + end + break + end + end + if psname~=metadata.fontname then + report_otf("fontname %a, fullname %a, psname %a",metadata.fontname,metadata.fullname,psname) + end + metadata.psname=psname + end end actions["cleanup tables"]=function(data,filename,raw) local duplicates=data.resources.duplicates @@ -5113,7 +5264,7 @@ actions["reorganize glyph lookups"]=function(data,filename,raw) end end local zero={ 0,0 } -actions["reorganize glyph anchors"]=function(data,filename,raw) +actions["reorganize glyph anchors"]=function(data,filename,raw) local descriptions=data.descriptions for unicode,description in next,descriptions do local anchors=description.glyph.anchors @@ -5315,9 +5466,13 @@ local function copytotfm(data,cache_id) local spaceunits=500 local spacer="space" local designsize=metadata.designsize or metadata.design_size or 100 + local minsize=metadata.minsize or metadata.design_range_bottom or designsize + local maxsize=metadata.maxsize or metadata.design_range_top or designsize local mathspecs=metadata.math if designsize==0 then designsize=100 + minsize=100 + maxsize=100 end if mathspecs then for name,value in next,mathspecs do @@ -5332,8 +5487,10 @@ local function copytotfm(data,cache_id) local d=descriptions[unicode] local m=d.math if m then - local variants=m.horiz_variants - local parts=m.horiz_parts + local italic=m.italic + local vitalic=m.vitalic + local variants=m.hvariants + local parts=m.hparts if variants then local c=character for i=1,#variants do @@ -5344,9 +5501,10 @@ local function copytotfm(data,cache_id) c.horiz_variants=parts elseif parts then character.horiz_variants=parts + italic=m.hitalic end - local variants=m.vert_variants - local parts=m.vert_parts + local variants=m.vvariants + local parts=m.vparts if variants then local c=character for i=1,#variants do @@ -5358,13 +5516,15 @@ local function copytotfm(data,cache_id) elseif parts then character.vert_variants=parts end - local italic_correction=m.vert_italic_correction - if italic_correction then - character.vert_italic_correction=italic_correction + if italic and italic~=0 then + character.italic=italic end - local top_accent=m.top_accent - if top_accent then - character.top_accent=top_accent + if vitalic and vitalic~=0 then + character.vert_italic=vitalic + end + local accent=m.accent + if accent then + character.accent=accent end local kerns=m.kerns if kerns then @@ -5376,14 +5536,14 @@ local function copytotfm(data,cache_id) local filename=constructors.checkedfilename(resources) local fontname=metadata.fontname local fullname=metadata.fullname or fontname - local psname=fontname or fullname - local units=metadata.units_per_em or 1000 + local psname=metadata.psname or fontname or fullname + local units=metadata.units or metadata.units_per_em or 1000 if units==0 then units=1000 - metadata.units_per_em=1000 + metadata.units=1000 report_otf("changing %a units to %a",0,units) end - local monospaced=metadata.isfixedpitch or (pfminfo.panose and pfminfo.panose.proportion=="Monospaced") + local monospaced=metadata.monospaced or metadata.isfixedpitch or (pfminfo.panose and pfminfo.panose.proportion=="Monospaced") local charwidth=pfminfo.avgwidth local charxheight=pfminfo.os2_xheight and pfminfo.os2_xheight>0 and pfminfo.os2_xheight local italicangle=metadata.italicangle @@ -5448,8 +5608,10 @@ local function copytotfm(data,cache_id) end end parameters.designsize=(designsize/10)*65536 - parameters.ascender=abs(metadata.ascent or 0) - parameters.descender=abs(metadata.descent or 0) + parameters.minsize=(minsize/10)*65536 + parameters.maxsize=(maxsize/10)*65536 + parameters.ascender=abs(metadata.ascender or metadata.ascent or 0) + parameters.descender=abs(metadata.descender or metadata.descent or 0) parameters.units=units properties.space=spacer properties.encodingbytes=2 @@ -5628,10 +5790,104 @@ function otf.scriptandlanguage(tfmdata,attr) local properties=tfmdata.properties return properties.script or "dflt",properties.language or "dflt" end +local function justset(coverage,unicode,replacement) + coverage[unicode]=replacement +end +otf.coverup={ + stepkey="subtables", + actions={ + substitution=justset, + alternate=justset, + multiple=justset, + ligature=justset, + kern=justset, + }, + register=function(coverage,lookuptype,format,feature,n,descriptions,resources) + local name=formatters["ctx_%s_%s"](feature,n) + if lookuptype=="kern" then + resources.lookuptypes[name]="position" + else + resources.lookuptypes[name]=lookuptype + end + for u,c in next,coverage do + local description=descriptions[u] + local slookups=description.slookups + if slookups then + slookups[name]=c + else + description.slookups={ [name]=c } + end + end + return name + end +} +local function getgsub(tfmdata,k,kind) + local description=tfmdata.descriptions[k] + if description then + local slookups=description.slookups + if slookups then + local shared=tfmdata.shared + local rawdata=shared and shared.rawdata + if rawdata then + local lookuptypes=rawdata.resources.lookuptypes + if lookuptypes then + local properties=tfmdata.properties + local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language) + if validlookups then + for l=1,#lookuplist do + local lookup=lookuplist[l] + local found=slookups[lookup] + if found then + return found,lookuptypes[lookup] + end + end + end + end + end + end + end +end +otf.getgsub=getgsub +function otf.getsubstitution(tfmdata,k,kind,value) + local found,kind=getgsub(tfmdata,k,kind) + if not found then + elseif kind=="substitution" then + return found + elseif kind=="alternate" then + local choice=tonumber(value) or 1 + return found[choice] or found[1] or k + end + return k +end +otf.getalternate=otf.getsubstitution +function otf.getmultiple(tfmdata,k,kind) + local found,kind=getgsub(tfmdata,k,kind) + if found and kind=="multiple" then + return found + end + return { k } +end +function otf.getkern(tfmdata,left,right,kind) + local kerns=getgsub(tfmdata,left,kind or "kern",true) + if kerns then + local found=kerns[right] + local kind=type(found) + if kind=="table" then + found=found[1][3] + elseif kind~="number" then + found=false + end + if found then + return found*tfmdata.parameters.factor + end + end + return 0 +end + +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-otf”] --- -end -- closure -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-otb” 93461f2f412a9b33b35a273c09b64291] --- if not modules then modules={} end modules ['font-otb']={ version=1.001, @@ -6158,8 +6414,8 @@ local function featuresinitializer(tfmdata,value) local collectlookups=otf.collectlookups local rawdata=tfmdata.shared.rawdata local properties=tfmdata.properties - local script=properties.script - local language=properties.language + local script=properties.script + local language=properties.language local basesubstitutions=rawdata.resources.features.gsub local basepositionings=rawdata.resources.features.gpos if basesubstitutions or basepositionings then @@ -6216,9 +6472,10 @@ directives.register("fonts.otf.loader.basemethod",function(v) end end) -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-otb”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-inj” 2e61e59f1931a84336c6aea812e219c2] --- if not modules then modules={} end modules ['font-inj']={ version=1.001, @@ -6337,7 +6594,8 @@ end function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext) local dx=factor*(exit[1]-entry[1]) local dy=-factor*(exit[2]-entry[2]) - local ws,wn=tfmstart.width,tfmnext.width + local ws=tfmstart.width + local wn=tfmnext.width nofregisteredcursives=nofregisteredcursives+1 if rlmode<0 then dx=-(dx+wn) @@ -6384,7 +6642,10 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne return dx,dy,nofregisteredcursives end function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) - local x,y,w,h=factor*spec[1],factor*spec[2],factor*spec[3],factor*spec[4] + local x=factor*spec[1] + local y=factor*spec[2] + local w=factor*spec[3] + local h=factor*spec[4] if x~=0 or w~=0 or y~=0 or h~=0 then local yoffset=y-h local leftkern=x @@ -6394,9 +6655,12 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) if rlmode and rlmode<0 then leftkern,rightkern=rightkern,leftkern end + if not injection then + injection="injections" + end local p=rawget(properties,current) if p then - local i=rawget(p,"injections") + local i=rawget(p,injection) if i then if leftkern~=0 then i.leftkern=(i.leftkern or 0)+leftkern @@ -6408,19 +6672,19 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) i.yoffset=(i.yoffset or 0)+yoffset end elseif leftkern~=0 or rightkern~=0 then - p.injections={ + p[injection]={ leftkern=leftkern, rightkern=rightkern, yoffset=yoffset, } else - p.injections={ + p[injection]={ yoffset=yoffset, } end elseif leftkern~=0 or rightkern~=0 then properties[current]={ - injections={ + [injection]={ leftkern=leftkern, rightkern=rightkern, yoffset=yoffset, @@ -6428,7 +6692,7 @@ function injections.setpair(current,factor,rlmode,r2lflag,spec,injection) } else properties[current]={ - injections={ + [injection]={ yoffset=yoffset, }, } @@ -6467,7 +6731,7 @@ function injections.setkern(current,factor,rlmode,x,injection) return 0,0 end end -function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase) +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk) local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) nofregisteredmarks=nofregisteredmarks+1 if rlmode>=0 then @@ -6477,11 +6741,15 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase) if p then local i=rawget(p,"injections") if i then - i.markx=dx - i.marky=dy - i.markdir=rlmode or 0 - i.markbase=nofregisteredmarks - i.markbasenode=base + if i.markmark then + else + i.markx=dx + i.marky=dy + i.markdir=rlmode or 0 + i.markbase=nofregisteredmarks + i.markbasenode=base + i.markmark=mkmk + end else p.injections={ markx=dx, @@ -6489,6 +6757,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase) markdir=rlmode or 0, markbase=nofregisteredmarks, markbasenode=base, + markmark=mkmk, } end else @@ -6499,6 +6768,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase) markdir=rlmode or 0, markbase=nofregisteredmarks, markbasenode=base, + markmark=mkmk, }, } end @@ -6603,27 +6873,33 @@ local function show_result(head) current=getnext(current) end end -local function collect_glyphs_1(head) - local glyphs,nofglyphs={},0 - local marks,nofmarks={},0 +local function collect_glyphs(head,offsets) + local glyphs,glyphi,nofglyphs={},{},0 + local marks,marki,nofmarks={},{},0 local nf,tm=nil,nil - for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then - local f=getfont(n) - if f~=nf then - nf=f - tm=fontdata[nf].resources.marks - end - if tm and tm[getchar(n)] then - nofmarks=nofmarks+1 - marks[nofmarks]=n - else - nofglyphs=nofglyphs+1 - glyphs[nofglyphs]=n - end + local n=head + local function identify(n,what) + local f=getfont(n) + if f~=nf then + nf=f + tm=fontdata[nf].resources + if tm then + tm=tm.marks + end + end + if tm and tm[getchar(n)] then + nofmarks=nofmarks+1 + marks[nofmarks]=n + marki[nofmarks]="injections" + else + nofglyphs=nofglyphs+1 + glyphs[nofglyphs]=n + glyphi[nofglyphs]=what + end + if offsets then local p=rawget(properties,n) if p then - local i=rawget(p,"injections") + local i=rawget(p,what) if i then local yoffset=i.yoffset if yoffset and yoffset~=0 then @@ -6633,36 +6909,47 @@ local function collect_glyphs_1(head) end end end - return glyphs,nofglyphs,marks,nofmarks -end -local function collect_glyphs_2(head) - local glyphs,nofglyphs={},0 - local marks,nofmarks={},0 - local nf,tm=nil,nil - for n in traverse_id(glyph_code,head) do - if getsubtype(n)<256 then - local f=getfont(n) - if f~=nf then - nf=f - tm=fontdata[nf].resources.marks - end - if tm and tm[getchar(n)] then - nofmarks=nofmarks+1 - marks[nofmarks]=n - else - nofglyphs=nofglyphs+1 - glyphs[nofglyphs]=n - end + while n do + local id=getid(n) + if id==glyph_code then + identify(n,"injections") + elseif id==disc_code then + local d=getfield(n,"pre") + if d then + for n in traverse_id(glyph_code,d) do + if getsubtype(n)<256 then + identify(n,"preinjections") + end + end + end + local d=getfield(n,"post") + if d then + for n in traverse_id(glyph_code,d) do + if getsubtype(n)<256 then + identify(n,"postinjections") + end + end + end + local d=getfield(n,"replace") + if d then + for n in traverse_id(glyph_code,d) do + if getsubtype(n)<256 then + identify(n,"replaceinjections") + end + end + end end + n=getnext(n) end - return glyphs,nofglyphs,marks,nofmarks + return glyphs,glyphi,nofglyphs,marks,marki,nofmarks end -local function inject_marks(marks,nofmarks) +local function inject_marks(marks,marki,nofmarks) for i=1,nofmarks do local n=marks[i] local pn=rawget(properties,n) if pn then - pn=rawget(pn,"injections") + local ni=marki[i] + local pn=rawget(pn,ni) if pn then local p=pn.markbasenode if p then @@ -6671,7 +6958,7 @@ local function inject_marks(marks,nofmarks) local rightkern=nil local pp=rawget(properties,p) if pp then - pp=rawget(pp,"injections") + pp=rawget(pp,ni) if pp then rightkern=pp.rightkern end @@ -6680,11 +6967,17 @@ local function inject_marks(marks,nofmarks) if pn.markdir<0 then ox=px-pn.markx-rightkern else - local leftkern=pp.leftkern - if leftkern then - ox=px-pn.markx + + + if false then + local leftkern=pp.leftkern + if leftkern then + ox=px-pn.markx-leftkern + else + ox=px-pn.markx + end else - ox=px-pn.markx-leftkern + ox=px-pn.markx end end else @@ -6697,12 +6990,7 @@ local function inject_marks(marks,nofmarks) end setfield(n,"xoffset",ox) local py=getfield(p,"yoffset") - local oy=0 - if marks[p] then - oy=py+pn.marky - else - oy=getfield(n,"yoffset")+py+pn.marky - end + local oy=getfield(n,"yoffset")+py+pn.marky setfield(n,"yoffset",oy) else end @@ -6710,14 +6998,14 @@ local function inject_marks(marks,nofmarks) end end end -local function inject_cursives(glyphs,nofglyphs) +local function inject_cursives(glyphs,glyphi,nofglyphs) local cursiveanchor,lastanchor=nil,nil local minc,maxc,last=0,0,nil for i=1,nofglyphs do local n=glyphs[i] local pn=rawget(properties,n) if pn then - pn=rawget(pn,"injections") + pn=rawget(pn,glyphi[i]) end if pn then local cursivex=pn.cursivex @@ -6783,22 +7071,59 @@ local function inject_cursives(glyphs,nofglyphs) end end end -local function inject_kerns(head,list,length) +local function inject_kerns(head,glist,ilist,length) for i=1,length do - local n=list[i] + local n=glist[i] local pn=rawget(properties,n) if pn then - local i=rawget(pn,"injections") - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - insert_node_before(head,n,newkern(leftkern)) - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(head,n,newkern(rightkern)) - end - end + local dp=nil + local dr=nil + local ni=ilist[i] + local p=nil + if ni=="injections" then + p=getprev(n) + if p then + local id=getid(p) + if id==disc_code then + dp=getfield(p,"post") + dr=getfield(p,"replace") + end + end + end + if dp then + local i=rawget(pn,"postinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + local t=find_tail(dp) + insert_node_after(dp,t,newkern(leftkern)) + setfield(p,"post",dp) + end + end + end + if dr then + local i=rawget(pn,"replaceinjections") + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + local t=find_tail(dr) + insert_node_after(dr,t,newkern(leftkern)) + setfield(p,"replace",dr) + end + end + else + local i=rawget(pn,ni) + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + insert_node_before(head,n,newkern(leftkern)) + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(head,n,newkern(rightkern)) + end + end + end end end end @@ -6807,23 +7132,18 @@ local function inject_everything(head,where) if trace_injections then trace(head,"everything") end - local glyphs,nofglyphs,marks,nofmarks - if nofregisteredpairs>0 then - glyphs,nofglyphs,marks,nofmarks=collect_glyphs_1(head) - else - glyphs,nofglyphs,marks,nofmarks=collect_glyphs_2(head) - end + local glyphs,glyphi,nofglyphs,marks,marki,nofmarks=collect_glyphs(head,nofregisteredpairs>0) if nofglyphs>0 then if nofregisteredcursives>0 then - inject_cursives(glyphs,nofglyphs) + inject_cursives(glyphs,glyphi,nofglyphs) end if nofregisteredmarks>0 then - inject_marks(marks,nofmarks) + inject_marks(marks,marki,nofmarks) end - inject_kerns(head,glyphs,nofglyphs) + inject_kerns(head,glyphs,glyphi,nofglyphs) end if nofmarks>0 then - inject_kerns(head,marks,nofmarks) + inject_kerns(head,marks,marki,nofmarks) end if keepregisteredcounts then keepregisteredcounts=false @@ -6841,7 +7161,7 @@ local function inject_kerns_only(head,where) trace(head,"kerns") end local n=head - local p=nil + local p=nil while n do local id=getid(n) if id==glyph_code then @@ -6857,6 +7177,7 @@ local function inject_kerns_only(head,where) if leftkern and leftkern~=0 then local t=find_tail(d) insert_node_after(d,t,newkern(leftkern)) + setfield(p,"post",d) end end end @@ -6868,6 +7189,7 @@ local function inject_kerns_only(head,where) if leftkern and leftkern~=0 then local t=find_tail(d) insert_node_after(d,t,newkern(leftkern)) + setfield(p,"replace",d) end end else @@ -6889,8 +7211,6 @@ local function inject_kerns_only(head,where) end end end - else - break end p=nil elseif id==disc_code then @@ -6945,7 +7265,7 @@ local function inject_kerns_only(head,where) local h=d for n in traverse_id(glyph_code,d) do if getsubtype(n)<256 then - local pn=rawget(properties,n) + local pn=rawget(properties,n) if pn then local i=rawget(pn,"replaceinjections") if i then @@ -6982,7 +7302,7 @@ local function inject_pairs_only(head,where) trace(head,"pairs") end local n=head - local p=nil + local p=nil while n do local id=getid(n) if id==glyph_code then @@ -6998,6 +7318,7 @@ local function inject_pairs_only(head,where) if leftkern and leftkern~=0 then local t=find_tail(d) insert_node_after(d,t,newkern(leftkern)) + setfield(p,"post",d) end end end @@ -7009,6 +7330,7 @@ local function inject_pairs_only(head,where) if leftkern and leftkern~=0 then local t=find_tail(d) insert_node_after(d,t,newkern(leftkern)) + setfield(p,"replace",d) end end else @@ -7023,24 +7345,22 @@ local function inject_pairs_only(head,where) else local i=rawget(pn,"injections") if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) - end local leftkern=i.leftkern if leftkern and leftkern~=0 then - insert_node_before(head,n,newkern(leftkern)) + head=insert_node_before(head,n,newkern(leftkern)) end local rightkern=i.rightkern if rightkern and rightkern~=0 then insert_node_after(head,n,newkern(rightkern)) n=getnext(n) end + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(n,"yoffset",yoffset) + end end end end - else - break end p=nil elseif id==disc_code then @@ -7049,16 +7369,12 @@ local function inject_pairs_only(head,where) local h=d for n in traverse_id(glyph_code,d) do if getsubtype(n)<256 then - local p=rawget(properties,n) - if p then - local i=rawget(p,"preinjections") + local pn=rawget(properties,n) + if pn then + local i=rawget(pn,"preinjections") if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) - end local leftkern=i.leftkern - if leftkern~=0 then + if leftkern and leftkern~=0 then h=insert_node_before(h,n,newkern(leftkern)) end local rightkern=i.rightkern @@ -7066,6 +7382,10 @@ local function inject_pairs_only(head,where) insert_node_after(head,n,newkern(rightkern)) n=getnext(n) end + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(n,"yoffset",yoffset) + end end end else @@ -7081,14 +7401,10 @@ local function inject_pairs_only(head,where) local h=d for n in traverse_id(glyph_code,d) do if getsubtype(n)<256 then - local p=rawget(properties,n) - if p then - local i=rawget(p,"postinjections") + local pn=rawget(properties,n) + if pn then + local i=rawget(pn,"postinjections") if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) - end local leftkern=i.leftkern if leftkern and leftkern~=0 then h=insert_node_before(h,n,newkern(leftkern)) @@ -7098,6 +7414,10 @@ local function inject_pairs_only(head,where) insert_node_after(head,n,newkern(rightkern)) n=getnext(n) end + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(n,"yoffset",yoffset) + end end end else @@ -7113,14 +7433,10 @@ local function inject_pairs_only(head,where) local h=d for n in traverse_id(glyph_code,d) do if getsubtype(n)<256 then - local p=rawget(properties,n) - if p then - local i=rawget(p,"replaceinjections") + local pn=rawget(properties,n) + if pn then + local i=rawget(pn,"replaceinjections") if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setfield(n,"yoffset",yoffset) - end local leftkern=i.leftkern if leftkern and leftkern~=0 then h=insert_node_before(h,n,newkern(leftkern)) @@ -7130,6 +7446,10 @@ local function inject_pairs_only(head,where) insert_node_after(head,n,newkern(rightkern)) n=getnext(n) end + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setfield(n,"yoffset",yoffset) + end end end else @@ -7154,7 +7474,7 @@ local function inject_pairs_only(head,where) end return tonode(head),true end -function injections.handler(head,where) +function injections.handler(head,where) if nofregisteredmarks>0 or nofregisteredcursives>0 then return inject_everything(head,where) elseif nofregisteredpairs>0 then @@ -7166,9 +7486,10 @@ function injections.handler(head,where) end end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-inj”] --- -do -- begin closure to overcome local limits and interference + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-ota” e18236703ac20ece7ff45f9209a9b9d6] --- if not modules then modules={} end modules ['font-otx']={ version=1.001, @@ -7543,9 +7864,10 @@ directives.register("otf.analyze.useunicodemarks",function(v) analyzers.useunicodemarks=v end) -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-ota”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-otn” f01870a8622259f58ffbdc5718a53377] --- if not modules then modules={} end modules ['font-otn']={ version=1.001, @@ -7554,14 +7876,12 @@ if not modules then modules={} end modules ['font-otn']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files", } -local concat,insert,remove=table.concat,table.insert,table.remove -local gmatch,gsub,find,match,lower,strip=string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip -local type,next,tonumber,tostring=type,next,tonumber,tostring -local lpegmatch=lpeg.match +local type,next,tonumber=type,next,tonumber local random=math.random local formatters=string.formatters local logs,trackers,nodes,attributes=logs,trackers,nodes,attributes local registertracker=trackers.register +local registerdirective=directives.register local fonts=fonts local otf=fonts.handlers.otf local trace_lookups=false registertracker("otf.lookups",function(v) trace_lookups=v end) @@ -7580,6 +7900,13 @@ local trace_applied=false registertracker("otf.applied",function(v) trace_applie local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end) local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end) local trace_directions=false registertracker("otf.directions",function(v) trace_directions=v end) +local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end) +local trace_discruns=false registertracker("otf.discruns",function(v) trace_discruns=v end) +local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) +local quit_on_no_replacement=true +local zwnjruns=true +registerdirective("otf.zwnjruns",function(v) zwnjruns=v end) +registerdirective("otf.chain.quitonnoreplacement",function(value) quit_on_no_replacement=value end) local report_direct=logs.reporter("fonts","otf direct") local report_subchain=logs.reporter("fonts","otf subchain") local report_chain=logs.reporter("fonts","otf chain") @@ -7633,13 +7960,10 @@ local disccodes=nodes.disccodes local glyph_code=nodecodes.glyph local glue_code=nodecodes.glue local disc_code=nodecodes.disc -local whatsit_code=nodecodes.whatsit local math_code=nodecodes.math local dir_code=whatcodes.dir local localpar_code=whatcodes.localpar local discretionary_code=disccodes.discretionary -local regular_code=disccodes.regular -local automatic_code=disccodes.automatic local ligature_code=glyphcodes.ligature local privateattribute=attributes.private local a_state=privateattribute('state') @@ -7673,6 +7997,13 @@ local lookuptags=false local handlers={} local rlmode=0 local featurevalue=false +local sweephead={} +local sweepnode=nil +local sweepprev=nil +local sweepnext=nil +local notmatchpre={} +local notmatchpost={} +local notmatchreplace={} local checkstep=(nodes and nodes.tracers and nodes.tracers.steppers.check) or function() end local registerstep=(nodes and nodes.tracers and nodes.tracers.steppers.register) or function() end local registermessage=(nodes and nodes.tracers and nodes.tracers.steppers.message) or function() end @@ -7742,6 +8073,65 @@ local function copy_glyph(g) return n end end +local function flattendisk(head,disc) + local replace=getfield(disc,"replace") + setfield(disc,"replace",nil) + free_node(disc) + if head==disc then + local next=getnext(disc) + if replace then + if next then + local tail=find_node_tail(replace) + setfield(tail,"next",next) + setfield(next,"prev",tail) + end + return replace,replace + elseif next then + return next,next + else + return + end + else + local next=getnext(disc) + local prev=getprev(disc) + if replace then + local tail=find_node_tail(replace) + if next then + setfield(tail,"next",next) + setfield(next,"prev",tail) + end + setfield(prev,"next",replace) + setfield(replace,"prev",prev) + return head,replace + else + if next then + setfield(next,"prev",prev) + end + setfield(prev,"next",next) + return head,next + end + end +end +local function appenddisc(disc,list) + local post=getfield(disc,"post") + local replace=getfield(disc,"replace") + local phead=list + local rhead=copy_node_list(list) + local ptail=find_node_tail(post) + local rtail=find_node_tail(replace) + if post then + setfield(ptail,"next",phead) + setfield(phead,"prev",ptail) + else + setfield(disc,"post",phead) + end + if replace then + setfield(rtail,"next",rhead) + setfield(rhead,"prev",rtail) + else + setfield(disc,"replace",rhead) + end +end local function markstoligature(kind,lookupname,head,start,stop,char) if start==stop and getchar(start)==char then return head,start @@ -7769,8 +8159,8 @@ local function markstoligature(kind,lookupname,head,start,stop,char) return head,base end end -local function getcomponentindex(start) - if getid(start)~=glyph_code then +local function getcomponentindex(start) + if getid(start)~=glyph_code then return 0 elseif getsubtype(start)==ligature_code then local i=0 @@ -7786,14 +8176,22 @@ local function getcomponentindex(start) return 0 end end +local a_noligature=attributes.private("noligature") local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) + if getattr(start,a_noligature)==1 then + return head,start + end if start==stop and getchar(start)==char then resetinjection(start) setfield(start,"char",char) return head,start end + local components=getfield(start,"components") + if components then + end local prev=getprev(start) local next=getnext(stop) + local comp=start setfield(start,"prev",nil) setfield(stop,"next",nil) local base=copy_glyph(start) @@ -7803,15 +8201,15 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun resetinjection(base) setfield(base,"char",char) setfield(base,"subtype",ligature_code) - setfield(base,"components",start) + setfield(base,"components",comp) if prev then setfield(prev,"next",base) end if next then setfield(next,"prev",base) end - setfield(base,"next",next) setfield(base,"prev",prev) + setfield(base,"next",next) if not discfound then local deletemarks=markflag~="mark" local components=start @@ -7829,7 +8227,9 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun if trace_marks then logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getligaindex(start)) end - head,current=insert_node_after(head,current,copy_node(start)) + local n=copy_node(start) + copyinjection(n,start) + head,current=insert_node_after(head,current,n) elseif trace_marks then logwarning("%s: delete mark %s",pref(kind,lookupname),gref(char)) end @@ -7848,16 +8248,75 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun end start=getnext(start) end + else + local discprev=getfield(discfound,"prev") + local discnext=getfield(discfound,"next") + if discprev and discnext then + local pre=getfield(discfound,"pre") + local post=getfield(discfound,"post") + local replace=getfield(discfound,"replace") + if not replace then + local prev=getfield(base,"prev") + local copied=copy_node_list(comp) + setfield(discnext,"prev",nil) + setfield(discprev,"next",nil) + if pre then + setfield(discprev,"next",pre) + setfield(pre,"prev",discprev) + end + pre=comp + if post then + local tail=find_node_tail(post) + setfield(tail,"next",discnext) + setfield(discnext,"prev",tail) + setfield(post,"prev",nil) + else + post=discnext + end + setfield(prev,"next",discfound) + setfield(discfound,"prev",prev) + setfield(discfound,"next",next) + setfield(next,"prev",discfound) + setfield(base,"next",nil) + setfield(base,"prev",nil) + setfield(base,"components",copied) + setfield(discfound,"pre",pre) + setfield(discfound,"post",post) + setfield(discfound,"replace",base) + setfield(discfound,"subtype",discretionary_code) + base=prev + end + end end return head,base end -function handlers.gsub_single(head,start,kind,lookupname,replacement) - if trace_singles then - logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement)) +local function multiple_glyphs(head,start,multiple,ignoremarks) + local nofmultiples=#multiple + if nofmultiples>0 then + resetinjection(start) + setfield(start,"char",multiple[1]) + if nofmultiples>1 then + local sn=getnext(start) + for k=2,nofmultiples do + local n=copy_node(start) + resetinjection(n) + setfield(n,"char",multiple[k]) + setfield(n,"prev",start) + setfield(n,"next",sn) + if sn then + setfield(sn,"prev",n) + end + setfield(start,"next",n) + start=n + end + end + return head,start,true + else + if trace_multiples then + logprocess("no multiple for %s",gref(getchar(start))) + end + return head,start,false end - resetinjection(start) - setfield(start,"char",replacement) - return head,start,true end local function get_alternative_glyph(start,alternatives,value,trace_alternatives) local n=#alternatives @@ -7890,33 +8349,13 @@ local function get_alternative_glyph(start,alternatives,value,trace_alternatives end end end -local function multiple_glyphs(head,start,multiple,ignoremarks) - local nofmultiples=#multiple - if nofmultiples>0 then - resetinjection(start) - setfield(start,"char",multiple[1]) - if nofmultiples>1 then - local sn=getnext(start) - for k=2,nofmultiples do - local n=copy_node(start) - resetinjection(n) - setfield(n,"char",multiple[k]) - setfield(n,"next",sn) - setfield(n,"prev",start) - if sn then - setfield(sn,"prev",n) - end - setfield(start,"next",n) - start=n - end - end - return head,start,true - else - if trace_multiples then - logprocess("no multiple for %s",gref(getchar(start))) - end - return head,start,false +function handlers.gsub_single(head,start,kind,lookupname,replacement) + if trace_singles then + logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement)) end + resetinjection(start) + setfield(start,"char",replacement) + return head,start,true end function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence) local value=featurevalue==true and tfmdata.shared.features[kind] or featurevalue @@ -7941,7 +8380,7 @@ function handlers.gsub_multiple(head,start,kind,lookupname,multiple,sequence) return multiple_glyphs(head,start,multiple,sequence.flags[1]) end function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) - local s,stop,discfound=getnext(start),nil,false + local s,stop=getnext(start),nil local startchar=getchar(start) if marks[startchar] then while s do @@ -7969,23 +8408,29 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) else head,start=markstoligature(kind,lookupname,head,start,stop,lig) end - return head,start,true + return head,start,true,false else end end else local skipmark=sequence.flags[1] + local discfound=false + local lastdisc=nil while s do local id=getid(s) - if id==glyph_code and getsubtype(s)<256 then - if getfont(s)==currentfont then + if id==glyph_code and getsubtype(s)<256 then + if getfont(s)==currentfont then local char=getchar(s) if skipmark and marks[char] then s=getnext(s) - else - local lg=ligature[char] + else + local lg=ligature[char] if lg then - stop=s + if not discfound and lastdisc then + discfound=lastdisc + lastdisc=nil + end + stop=s ligature=lg s=getnext(s) else @@ -7996,13 +8441,13 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) break end elseif id==disc_code then - discfound=true + lastdisc=s s=getnext(s) else break end end - local lig=ligature.ligature + local lig=ligature.ligature if lig then if stop then if trace_ligatures then @@ -8019,12 +8464,71 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(kind,lookupname),gref(startchar),gref(lig)) end end - return head,start,true + return head,start,true,discfound else end end + return head,start,false,discfound +end +function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence,injection) + local startchar=getchar(start) + local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) + end return head,start,false end +function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence,lookuphash,i,injection) + local snext=getnext(start) + if not snext then + return head,start,false + else + local prev=start + local done=false + local factor=tfmdata.parameters.factor + local lookuptype=lookuptypes[lookupname] + while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do + local nextchar=getchar(snext) + local krn=kerns[nextchar] + if not krn and marks[nextchar] then + prev=snext + snext=getnext(snext) + else + if not krn then + elseif type(krn)=="table" then + if lookuptype=="pair" then + local a,b=krn[2],krn[3] + if a and #a>0 then + local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b and #b>0 then + local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + else + report_process("%s: check this out (old kern stuff)",pref(kind,lookupname)) + end + done=true + elseif krn~=0 then + local k=setkern(snext,factor,rlmode,krn,injection) + if trace_kerns then + logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) + end + done=true + end + break + end + end + return head,start,done + end +end function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence) local markchar=getchar(start) if marks[markchar] then @@ -8177,7 +8681,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence if al[anchor] then local ma=markanchors[anchor] if ma then - local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) + local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar],true) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -8255,65 +8759,6 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) return head,start,false end end -function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) - local startchar=getchar(start) - local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) - if trace_kerns then - logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) - end - return head,start,false -end -function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) - local snext=getnext(start) - if not snext then - return head,start,false - else - local prev,done=start,false - local factor=tfmdata.parameters.factor - local lookuptype=lookuptypes[lookupname] - while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do - local nextchar=getchar(snext) - local krn=kerns[nextchar] - if not krn and marks[nextchar] then - prev=snext - snext=getnext(snext) - else - if not krn then - elseif type(krn)=="table" then - if lookuptype=="pair" then - local a,b=krn[2],krn[3] - if a and #a>0 then - local startchar=getchar(start) - local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) - if trace_kerns then - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) - end - end - if b and #b>0 then - local startchar=getchar(start) - local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) - if trace_kerns then - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) - end - end - else - report_process("%s: check this out (old kern stuff)",pref(kind,lookupname)) - end - done=true - elseif krn~=0 then - local k=setkern(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) - end - done=true - end - break - end - end - return head,start,done - end -end -local chainmores={} local chainprocs={} local function logprocess(...) if trace_steps then @@ -8333,10 +8778,6 @@ function chainprocs.chainsub(head,start,stop,kind,chainname,currentcontext,looku logwarning("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname)) return head,start,false end -function chainmores.chainsub(head,start,stop,kind,chainname,currentcontext,lookuphash,lookuplist,chainlookupname,n) - logprocess("%s: a direct call to chainsub cannot happen",cref(kind,chainname,chainlookupname)) - return head,start,false -end function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements) local char=getchar(start) local replacement=replacements[char] @@ -8355,7 +8796,7 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo local current=start local subtables=currentlookup.subtables if #subtables>1 then - logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," ")) + logwarning("todo: check if we need to loop over the replacements: % t",subtables) end while current do if getid(current)==glyph_code then @@ -8389,7 +8830,6 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo end return head,start,false end -chainmores.gsub_single=chainprocs.gsub_single function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) local startchar=getchar(start) local subtables=currentlookup.subtables @@ -8414,7 +8854,6 @@ function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext, end return head,start,false end -chainmores.gsub_multiple=chainprocs.gsub_multiple function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) local current=start local subtables=currentlookup.subtables @@ -8456,7 +8895,6 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext end return head,start,false end -chainmores.gsub_alternate=chainprocs.gsub_alternate function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex) local startchar=getchar(start) local subtables=currentlookup.subtables @@ -8476,13 +8914,19 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, local s=getnext(start) local discfound=false local last=stop - local nofreplacements=0 + local nofreplacements=1 local skipmark=currentlookup.flags[1] while s do local id=getid(s) if id==disc_code then - s=getnext(s) - discfound=true + if not discfound then + discfound=s + end + if s==stop then + break + else + s=getnext(s) + end else local schar=getchar(s) if skipmark and marks[schar] then @@ -8515,7 +8959,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, end end head,start=toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound) - return head,start,true,nofreplacements + return head,start,true,nofreplacements,discfound elseif trace_bugs then if start==stop then logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) @@ -8525,9 +8969,82 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, end end end - return head,start,false,0 + return head,start,false,0,false +end +function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) + local startchar=getchar(start) + local subtables=currentlookup.subtables + local lookupname=subtables[1] + local kerns=lookuphash[lookupname] + if kerns then + kerns=kerns[startchar] + if kerns then + local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns) + if trace_kerns then + logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) + end + end + end + return head,start,false +end +function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) + local snext=getnext(start) + if snext then + local startchar=getchar(start) + local subtables=currentlookup.subtables + local lookupname=subtables[1] + local kerns=lookuphash[lookupname] + if kerns then + kerns=kerns[startchar] + if kerns then + local lookuptype=lookuptypes[lookupname] + local prev,done=start,false + local factor=tfmdata.parameters.factor + while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do + local nextchar=getchar(snext) + local krn=kerns[nextchar] + if not krn and marks[nextchar] then + prev=snext + snext=getnext(snext) + else + if not krn then + elseif type(krn)=="table" then + if lookuptype=="pair" then + local a,b=krn[2],krn[3] + if a and #a>0 then + local startchar=getchar(start) + local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a) + if trace_kerns then + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b and #b>0 then + local startchar=getchar(start) + local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b) + if trace_kerns then + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) + end + end + else + report_process("%s: check this out (old kern stuff)",cref(kind,chainname,chainlookupname)) + end + done=true + elseif krn~=0 then + local k=setkern(snext,factor,rlmode,krn) + if trace_kerns then + logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) + end + done=true + end + break + end + end + return head,start,done + end + end + end + return head,start,false end -chainmores.gsub_ligature=chainprocs.gsub_ligature function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) local markchar=getchar(start) if marks[markchar] then @@ -8691,7 +9208,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext if al[anchor] then local ma=markanchors[anchor] if ma then - local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) + local dx,dy,bound=setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar],true) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -8778,113 +9295,286 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l end return head,start,false end -function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local startchar=getchar(start) - local subtables=currentlookup.subtables - local lookupname=subtables[1] - local kerns=lookuphash[lookupname] - if kerns then - kerns=kerns[startchar] - if kerns then - local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) - if trace_kerns then - logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),dx,dy,w,h) +local function show_skip(kind,chainname,char,ck,class) + if ck[9] then + logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a, %a => %a",cref(kind,chainname),gref(char),class,ck[1],ck[2],ck[9],ck[10]) + else + logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(kind,chainname),gref(char),class,ck[1],ck[2]) + end +end +local function chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,chainindex,sequence,chainproc) + if not start then + return head,start,false + end + local startishead=start==head + local seq=ck[3] + local f=ck[4] + local l=ck[5] + local s=#seq + local done=false + local sweepnode=sweepnode + local sweeptype=sweeptype + local sweepoverflow=false + local checkdisc=getprev(head) + local keepdisc=not sweepnode + local lookaheaddisc=nil + local backtrackdisc=nil + local current=start + local last=start + local prev=getprev(start) + local i=f + while i<=l do + local id=getid(current) + if id==glyph_code then + i=i+1 + last=current + current=getnext(current) + elseif id==disc_code then + if keepdisc then + keepdisc=false + if notmatchpre[current]~=notmatchreplace[current] then + lookaheaddisc=current + end + local replace=getfield(current,"replace") + while replace and i<=l do + if getid(replace)==glyph_code then + i=i+1 + end + replace=getnext(replace) + end + last=current + current=getnext(c) + else + head,current=flattendisk(head,current) + end + else + last=current + current=getnext(current) + end + if current then + elseif sweepoverflow then + break + elseif sweeptype=="post" or sweeptype=="replace" then + current=getnext(sweepnode) + if current then + sweeptype=nil + sweepoverflow=true + else + break end end end - return head,start,false -end -chainmores.gpos_single=chainprocs.gpos_single -function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local snext=getnext(start) - if snext then - local startchar=getchar(start) - local subtables=currentlookup.subtables - local lookupname=subtables[1] - local kerns=lookuphash[lookupname] - if kerns then - kerns=kerns[startchar] - if kerns then - local lookuptype=lookuptypes[lookupname] - local prev,done=start,false - local factor=tfmdata.parameters.factor - while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do - local nextchar=getchar(snext) - local krn=kerns[nextchar] - if not krn and marks[nextchar] then - prev=snext - snext=getnext(snext) - else - if not krn then - elseif type(krn)=="table" then - if lookuptype=="pair" then - local a,b=krn[2],krn[3] - if a and #a>0 then - local startchar=getchar(start) - local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) - if trace_kerns then - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) - end - end - if b and #b>0 then - local startchar=getchar(start) - local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) - if trace_kerns then - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) - end - end - else - report_process("%s: check this out (old kern stuff)",cref(kind,chainname,chainlookupname)) - local a,b=krn[2],krn[6] - if a and a~=0 then - local k=setkern(snext,factor,rlmode,a) - if trace_kerns then - logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) - end - end - if b and b~=0 then - logwarning("%s: ignoring second kern xoff %s",cref(kind,chainname,chainlookupname),b*factor) - end - end - done=true - elseif krn~=0 then - local k=setkern(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) - end - done=true + if sweepoverflow then + local prev=current and getprev(current) + if not current or prev~=sweepnode then + local head=getnext(sweepnode) + local tail=nil + if prev then + tail=prev + setfield(current,"prev",sweepnode) + else + tail=find_node_tail(head) + end + setfield(sweepnode,"next",current) + setfield(head,"prev",nil) + setfield(tail,"next",nil) + appenddisc(sweepnode,head) + end + end + if l<s then + local i=l + local t=sweeptype=="post" or sweeptype=="replace" + while current and i<s do + local id=getid(current) + if id==glyph_code then + i=i+1 + current=getnext(current) + elseif id==disc_code then + if keepdisc then + keepdisc=false + if notmatchpre[current]~=notmatchreplace[current] then + lookaheaddisc=current + end + local replace=getfield(c,"replace") + while replace and i<s do + if getid(replace)==glyph_code then + i=i+1 end - break + replace=getnext(replace) end + current=getnext(current) + elseif notmatchpre[current]~=notmatchreplace[current] then + head,current=flattendisk(head,current) + else + current=getnext(current) + end + else + current=getnext(current) + end + if not current and t then + current=getnext(sweepnode) + if current then + sweeptype=nil end - return head,start,done end end end - return head,start,false -end -chainmores.gpos_pair=chainprocs.gpos_pair -local function show_skip(kind,chainname,char,ck,class) - if ck[9] then - logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a, %a => %a",cref(kind,chainname),gref(char),class,ck[1],ck[2],ck[9],ck[10]) + if f>1 then + local current=prev + local i=f + local t=sweeptype=="pre" or sweeptype=="replace" + if not current and t and current==checkdisk then + current=getprev(sweepnode) + end + while current and i>1 do + local id=getid(current) + if id==glyph_code then + i=i-1 + elseif id==disc_code then + if keepdisc then + keepdisc=false + if notmatchpost[current]~=notmatchreplace[current] then + backtrackdisc=current + end + local replace=getfield(current,"replace") + while replace and i>1 do + if getid(replace)==glyph_code then + i=i-1 + end + replace=getnext(replace) + end + elseif notmatchpost[current]~=notmatchreplace[current] then + head,current=flattendisk(head,current) + end + end + current=getprev(current) + if t and current==checkdisk then + current=getprev(sweepnode) + end + end + end + local ok=false + if lookaheaddisc then + local cf=start + local cl=getprev(lookaheaddisc) + local cprev=getprev(start) + local insertedmarks=0 + while cprev and getid(cf)==glyph_code and getfont(cf)==currentfont and getsubtype(cf)<256 and marks[getchar(cf)] do + insertedmarks=insertedmarks+1 + cf=cprev + startishead=cf==head + cprev=getprev(cprev) + end + setfield(lookaheaddisc,"prev",cprev) + if cprev then + setfield(cprev,"next",lookaheaddisc) + end + setfield(cf,"prev",nil) + setfield(cl,"next",nil) + if startishead then + head=lookaheaddisc + end + local replace=getfield(lookaheaddisc,"replace") + local pre=getfield(lookaheaddisc,"pre") + local new=copy_node_list(cf) + local cnew=new + for i=1,insertedmarks do + cnew=getnext(cnew) + end + local clast=cnew + for i=f,l do + clast=getnext(clast) + end + if not notmatchpre[lookaheaddisc] then + cf,start,ok=chainproc(cf,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence) + end + if not notmatchreplace[lookaheaddisc] then + new,cnew,ok=chainproc(new,cnew,clast,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence) + end + if pre then + setfield(cl,"next",pre) + setfield(pre,"prev",cl) + end + if replace then + local tail=find_node_tail(new) + setfield(tail,"next",replace) + setfield(replace,"prev",tail) + end + setfield(lookaheaddisc,"pre",cf) + setfield(lookaheaddisc,"replace",new) + start=getprev(lookaheaddisc) + sweephead[cf]=getnext(clast) + sweephead[new]=getnext(last) + elseif backtrackdisc then + local cf=getnext(backtrackdisc) + local cl=start + local cnext=getnext(start) + local insertedmarks=0 + while cnext and getid(cnext)==glyph_code and getfont(cnext)==currentfont and getsubtype(cnext)<256 and marks[getchar(cnext)] do + insertedmarks=insertedmarks+1 + cl=cnext + cnext=getnext(cnext) + end + if cnext then + setfield(cnext,"prev",backtrackdisc) + end + setfield(backtrackdisc,"next",cnext) + setfield(cf,"prev",nil) + setfield(cl,"next",nil) + local replace=getfield(backtrackdisc,"replace") + local post=getfield(backtrackdisc,"post") + local new=copy_node_list(cf) + local cnew=find_node_tail(new) + for i=1,insertedmarks do + cnew=getprev(cnew) + end + local clast=cnew + for i=f,l do + clast=getnext(clast) + end + if not notmatchpost[backtrackdisc] then + cf,start,ok=chainproc(cf,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence) + end + if not notmatchreplace[backtrackdisc] then + new,cnew,ok=chainproc(new,cnew,clast,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence) + end + if post then + local tail=find_node_tail(post) + setfield(tail,"next",cf) + setfield(cf,"prev",tail) + else + post=cf + end + if replace then + local tail=find_node_tail(replace) + setfield(tail,"next",new) + setfield(new,"prev",tail) + else + replace=new + end + setfield(backtrackdisc,"post",post) + setfield(backtrackdisc,"replace",replace) + start=getprev(backtrackdisc) + sweephead[post]=getnext(clast) + sweephead[replace]=getnext(last) else - logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(kind,chainname),gref(char),class,ck[1],ck[2]) + head,start,ok=chainproc(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence) end + return head,start,ok end -local quit_on_no_replacement=true -directives.register("otf.chain.quitonnoreplacement",function(value) - quit_on_no_replacement=value -end) local function normal_handle_contextchain(head,start,kind,chainname,contexts,sequence,lookuphash) + local sweepnode=sweepnode + local sweeptype=sweeptype + local diskseen=false + local checkdisc=getprev(head) local flags=sequence.flags local done=false local skipmark=flags[1] local skipligature=flags[2] local skipbase=flags[3] - local someskip=skipmark or skipligature or skipbase - local markclass=sequence.markclass + local markclass=sequence.markclass local skipped=false - for k=1,#contexts do + for k=1,#contexts do local match=true local current=start local last=start @@ -8894,14 +9584,20 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if s==1 then match=getid(current)==glyph_code and getfont(current)==currentfont and getsubtype(current)<256 and seq[1][getchar(current)] else - local f,l=ck[4],ck[5] + local f=ck[4] + local l=ck[5] if f==1 and f==l then else if f==l then else + local discfound=nil local n=f+1 last=getnext(last) while n<=l do + if not last and (sweeptype=="post" or sweeptype=="replace") then + last=getnext(sweepnode) + sweeptype=nil + end if last then local id=getid(last) if id==glyph_code then @@ -8909,7 +9605,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq local char=getchar(last) local ccd=descriptions[char] if ccd then - local class=ccd.class + local class=ccd.class or "base" if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then skipped=true if trace_skips then @@ -8922,18 +9618,76 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end n=n+1 else - match=false + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpre[discfound] + else + match=false + end break end else - match=false + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpre[discfound] + else + match=false + end break end else - match=false + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpre[discfound] + else + match=false + end break end elseif id==disc_code then + diskseen=true + discfound=last + notmatchpre[last]=nil + notmatchpost[last]=true + notmatchreplace[last]=nil + local pre=getfield(last,"pre") + local replace=getfield(last,"replace") + if pre then + local n=n + while pre do + if seq[n][getchar(pre)] then + n=n+1 + pre=getnext(pre) + if n>l then + break + end + else + notmatchpre[last]=true + break + end + end + if n<=l then + notmatchpre[last]=true + end + else + notmatchpre[last]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + replace=getnext(replace) + if n>l then + break + end + else + notmatchreplace[last]=true + match=not notmatchpre[last] + break + end + end + match=not notmatchpre[last] + end last=getnext(last) else match=false @@ -8949,49 +9703,132 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if match and f>1 then local prev=getprev(start) if prev then - local n=f-1 - while n>=1 do - if prev then - local id=getid(prev) - if id==glyph_code then - if getfont(prev)==currentfont and getsubtype(prev)<256 then - local char=getchar(prev) - local ccd=descriptions[char] - if ccd then - local class=ccd.class - if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then - skipped=true - if trace_skips then - show_skip(kind,chainname,char,ck,class) + if prev==checkdisc and (sweeptype=="pre" or sweeptype=="replace") then + prev=getprev(sweepnode) + end + if prev then + local discfound=nil + local n=f-1 + while n>=1 do + if prev then + local id=getid(prev) + if id==glyph_code then + if getfont(prev)==currentfont and getsubtype(prev)<256 then + local char=getchar(prev) + local ccd=descriptions[char] + if ccd then + local class=ccd.class + if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then + skipped=true + if trace_skips then + show_skip(kind,chainname,char,ck,class) + end + elseif seq[n][char] then + n=n -1 + else + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpost[discfound] + else + match=false + end + break end - elseif seq[n][char] then - n=n -1 else - match=false + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpost[discfound] + else + match=false + end break end else - match=false + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpost[discfound] + else + match=false + end break end + elseif id==disc_code then + diskseen=true + discfound=prev + notmatchpre[prev]=true + notmatchpost[prev]=nil + notmatchreplace[prev]=nil + local pre=getfield(prev,"pre") + local post=getfield(prev,"post") + local replace=getfield(prev,"replace") + if pre~=start and post~=start and replace~=start then + if post then + local n=n + local posttail=find_node_tail(post) + while posttail do + if seq[n][getchar(posttail)] then + n=n-1 + if posttail==post then + break + else + posttail=getprev(posttail) + if n<1 then + break + end + end + else + notmatchpost[prev]=true + break + end + end + if n>=1 then + notmatchpost[prev]=true + end + else + notmatchpost[prev]=true + end + if replace then + local replacetail=find_node_tail(replace) + while replacetail do + if seq[n][getchar(replacetail)] then + n=n-1 + if replacetail==replace then + break + else + replacetail=getprev(replacetail) + if n<1 then + break + end + end + else + notmatchreplace[prev]=true + match=not notmatchpost[prev] + break + end + end + if not match then + break + end + else + end + else + end + elseif seq[n][32] then + n=n -1 else match=false break end - elseif id==disc_code then - elseif seq[n][32] then - n=n -1 + prev=getprev(prev) + elseif seq[n][32] then + n=n-1 else match=false break end - prev=getprev(prev) - elseif seq[n][32] then - n=n -1 - else - match=false - break end + else + match=false end else match=false @@ -8999,7 +9836,13 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end if match and s>l then local current=last and getnext(last) + if not current then + if sweeptype=="post" or sweeptype=="replace" then + current=getnext(sweepnode) + end + end if current then + local discfound=nil local n=l+1 while n<=s do if current then @@ -9018,18 +9861,79 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq elseif seq[n][char] then n=n+1 else - match=false + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpre[discfound] + else + match=false + end break end else - match=false + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpre[discfound] + else + match=false + end break end else - match=false + if discfound then + notmatchreplace[discfound]=true + match=not notmatchpre[discfound] + else + match=false + end break end elseif id==disc_code then + diskseen=true + discfound=current + notmatchpre[current]=nil + notmatchpost[current]=true + notmatchreplace[current]=nil + local pre=getfield(current,"pre") + local replace=getfield(current,"replace") + if pre then + local n=n + while pre do + if seq[n][getchar(pre)] then + n=n+1 + pre=getnext(pre) + if n>s then + break + end + else + notmatchpre[current]=true + break + end + end + if n<=s then + notmatchpre[current]=true + end + else + notmatchpre[current]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + replace=getnext(replace) + if n>s then + break + end + else + notmatchreplace[current]=true + match=notmatchpre[current] + break + end + end + if not match then + break + end + else + end elseif seq[n][32] then n=n+1 else @@ -9050,6 +9954,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end if match then + local diskchain=diskseen or sweepnode if trace_contexts then local rule,lookuptype,f,l=ck[1],ck[2],ck[4],ck[5] local char=getchar(start) @@ -9068,10 +9973,14 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq local chainlookupname=chainlookups[1] local chainlookup=lookuptable[chainlookupname] if chainlookup then - local cp=chainprocs[chainlookup.type] - if cp then + local chainproc=chainprocs[chainlookup.type] + if chainproc then local ok - head,start,ok=cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence) + if diskchain then + head,start,ok=chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence,chainproc) + else + head,start,ok=chainproc(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence) + end if ok then done=true end @@ -9083,13 +9992,13 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end else local i=1 - while true do + while start and true do if skipped then - while true do + while true do local char=getchar(start) local ccd=descriptions[char] if ccd then - local class=ccd.class + local class=ccd.class or "base" if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then start=getnext(start) else @@ -9105,26 +10014,33 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if not chainlookup then i=i+1 else - local cp=chainmores[chainlookup.type] - if not cp then + local chainproc=chainprocs[chainlookup.type] + if not chainproc then logprocess("%s: %s is not yet supported",cref(kind,chainname,chainlookupname),chainlookup.type) i=i+1 else local ok,n - head,start,ok,n=cp(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,i,sequence) + if diskchain then + head,start,ok=chaindisk(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,nil,sequence,chainproc) + else + head,start,ok,n=chainproc(head,start,last,kind,chainname,ck,lookuphash,chainlookup,chainlookupname,i,sequence) + end if ok then done=true - i=i+(n or 1) - else - i=i+1 + if n and n>1 then + if i+n>nofchainlookups then + break + else + end + end end + i=i+1 end end - if i>nofchainlookups then + if i>nofchainlookups or not start then break elseif start then start=getnext(start) - else end end end @@ -9139,8 +10055,16 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end end + if done then + break + end end end + if diskseen then + notmatchpre={} + notmatchpost={} + notmatchreplace={} + end return head,start,done end local verbose_handle_contextchain=function(font,...) @@ -9211,7 +10135,7 @@ local function initialize(sequence,script,language,enabled) local scripts=features[kind] local languages=scripts[script] or scripts[wildcard] if languages and (languages[language] or languages[wildcard]) then - return { valid,autofeatures[kind] or false,sequence.chain or 0,kind,sequence } + return { valid,autofeatures[kind] or false,sequence,kind } end end end @@ -9251,6 +10175,175 @@ function otf.dataset(tfmdata,font) end return rl end +local function kernrun(disc,run) + if trace_kernruns then + report_run("kern") + end + local prev=getprev(disc) + local next=getnext(disc) + local pre=getfield(disc,"pre") + local post=getfield(disc,"post") + local replace=getfield(disc,"replace") + local prevmarks=prev + while prevmarks and getid(prevmarks)==glyph_code and marks[getchar(prevmarks)] and getfont(prevmarks)==currentfont and getsubtype(prevmarks)<256 do + prevmarks=getprev(prevmarks) + end + if prev and (pre or replace) and not (getid(prev)==glyph_code and getfont(prev)==currentfont and getsubtype(prev)<256) then + prev=false + end + if next and (post or replace) and not (getid(next)==glyph_code and getfont(next)==currentfont and getsubtype(next)<256) then + next=false + end + if not pre then + elseif prev then + local nest=getprev(pre) + setfield(pre,"prev",prev) + setfield(prev,"next",pre) + run(prevmarks,"preinjections") + setfield(pre,"prev",nest) + setfield(prev,"next",disc) + else + run(pre,"preinjections") + end + if not post then + elseif next then + local tail=find_node_tail(post) + setfield(tail,"next",next) + setfield(next,"prev",tail) + run(post,"postinjections",next) + setfield(tail,"next",nil) + setfield(next,"prev",disc) + else + run(post,"postinjections") + end + if not replace and prev and next then + setfield(prev,"next",next) + setfield(next,"prev",prev) + run(prevmarks,"injections",next) + setfield(prev,"next",disc) + setfield(next,"prev",disc) + elseif prev and next then + local tail=find_node_tail(replace) + local nest=getprev(replace) + setfield(replace,"prev",prev) + setfield(prev,"next",replace) + setfield(tail,"next",next) + setfield(next,"prev",tail) + run(prevmarks,"replaceinjections",next) + setfield(replace,"prev",nest) + setfield(prev,"next",disc) + setfield(tail,"next",nil) + setfield(next,"prev",disc) + elseif prev then + local nest=getprev(replace) + setfield(replace,"prev",prev) + setfield(prev,"next",replace) + run(prevmarks,"replaceinjections") + setfield(replace,"prev",nest) + setfield(prev,"next",disc) + elseif next then + local tail=find_node_tail(replace) + setfield(tail,"next",next) + setfield(next,"prev",tail) + run(replace,"replaceinjections",next) + setfield(tail,"next",nil) + setfield(next,"prev",disc) + else + run(replace,"replaceinjections") + end +end +local function comprun(disc,run) + if trace_compruns then + report_run("comp: %s",languages.serializediscretionary(disc)) + end + local pre=getfield(disc,"pre") + if pre then + sweepnode=disc + sweeptype="pre" + local new,done=run(pre) + if done then + setfield(disc,"pre",new) + end + end + local post=getfield(disc,"post") + if post then + sweepnode=disc + sweeptype="post" + local new,done=run(post) + if done then + setfield(disc,"post",new) + end + end + local replace=getfield(disc,"replace") + if replace then + sweepnode=disc + sweeptype="replace" + local new,done=run(replace) + if done then + setfield(disc,"replace",new) + end + end + sweepnode=nil + sweeptype=nil +end +local function testrun(disc,trun,crun) + local next=getnext(disc) + if next then + local replace=getfield(disc,"replace") + if replace then + local prev=getprev(disc) + if prev then + local tail=find_node_tail(replace) + setfield(tail,"next",next) + setfield(next,"prev",tail) + if trun(replace,next) then + setfield(disc,"replace",nil) + setfield(prev,"next",replace) + setfield(replace,"prev",prev) + setfield(next,"prev",tail) + setfield(tail,"next",next) + setfield(disc,"prev",nil) + setfield(disc,"next",nil) + flush_node_list(disc) + return replace + else + setfield(tail,"next",nil) + setfield(next,"prev",disc) + end + else + end + else + end + else + end + comprun(disc,crun) + return next +end +local function discrun(disc,drun,krun) + local next=getnext(disc) + local prev=getprev(disc) + if trace_discruns then + report_run("disc") + end + if next and prev then + setfield(prev,"next",next) + drun(prev) + setfield(prev,"next",disc) + end + local pre=getfield(disc,"pre") + if not pre then + elseif prev then + local nest=getprev(pre) + setfield(pre,"prev",prev) + setfield(prev,"next",pre) + krun(prev,"preinjections") + setfield(pre,"prev",nest) + setfield(prev,"next",disc) + else + krun(pre,"preinjections") + end + return next +end local function featuresprocessor(head,font,attr) local lookuphash=lookuphashes[font] if not lookuphash then @@ -9271,23 +10364,25 @@ local function featuresprocessor(head,font,attr) lookuptags=resources.lookuptags currentfont=font rlmode=0 + sweephead={} local sequences=resources.sequences local done=false local datasets=otf.dataset(tfmdata,font,attr) local dirstack={} for s=1,#datasets do local dataset=datasets[s] - featurevalue=dataset[1] - local sequence=dataset[5] + featurevalue=dataset[1] + local attribute=dataset[2] + local sequence=dataset[3] + local kind=dataset[4] local rlparmode=0 local topstack=0 local success=false - local attribute=dataset[2] - local chain=dataset[3] local typ=sequence.type + local gpossing=typ=="gpos_single" or typ=="gpos_pair" local subtables=sequence.subtables - if chain<0 then - local handler=handlers[typ] + local handler=handlers[typ] + if typ=="gsub_reversecontextchain" then local start=find_node_tail(head) while start do local id=getid(start) @@ -9300,13 +10395,14 @@ local function featuresprocessor(head,font,attr) a=true end if a then + local char=getchar(start) for i=1,#subtables do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[char] if lookupmatch then - head,start,success=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + head,start,success=handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,i) if success then break end @@ -9327,7 +10423,6 @@ local function featuresprocessor(head,font,attr) end end else - local handler=handlers[typ] local ns=#subtables local start=head rlmode=0 @@ -9337,12 +10432,19 @@ local function featuresprocessor(head,font,attr) if not lookupcache then report_missing_cache(typ,lookupname) else - local function subrun(start) - local head=start + local function c_run(head) local done=false + local start=sweephead[head] + if start then + sweephead[head]=nil + else + start=head + end while start do local id=getid(start) - if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then + if id~=glyph_code then + start=getnext(start) + elseif getfont(start)==font and getsubtype(start)<256 then local a=getattr(start,0) if a then a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) @@ -9353,7 +10455,7 @@ local function featuresprocessor(head,font,attr) local lookupmatch=lookupcache[getchar(start)] if lookupmatch then local ok - head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) + head,start,ok=handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,1) if ok then done=true end @@ -9363,43 +10465,98 @@ local function featuresprocessor(head,font,attr) start=getnext(start) end else - start=getnext(start) + return head,false end end if done then - success=true - return head + success=true end + return head,done end - local function kerndisc(disc) - local prev=getprev(disc) - local next=getnext(disc) - if prev and next then - setfield(prev,"next",next) - local a=getattr(prev,0) - if a then - a=(a==attr) and (not attribute or getprop(prev,a_state)==attribute) + local function t_run(start,stop) + while start~=stop do + local id=getid(start) + if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) + if a then + a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) + else + a=not attribute or getprop(start,a_state)==attribute + end + if a then + local lookupmatch=lookupcache[getchar(start)] + if lookupmatch then + local s=getnext(start) + local l=nil + while s do + local lg=lookupmatch[getchar(s)] + if lg then + l=lg + s=getnext(s) + else + break + end + end + if l and l.ligature then + return true + end + end + end + start=getnext(start) else - a=not attribute or getprop(prev,a_state)==attribute + break end - if a then - local lookupmatch=lookupcache[getchar(prev)] - if lookupmatch then - local h,d,ok=handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) - if ok then - done=true - success=true + end + end + local function d_run(prev) + local a=getattr(prev,0) + if a then + a=(a==attr) and (not attribute or getprop(prev,a_state)==attribute) + else + a=not attribute or getprop(prev,a_state)==attribute + end + if a then + local lookupmatch=lookupcache[getchar(prev)] + if lookupmatch then + local h,d,ok=handler(head,prev,kind,lookupname,lookupmatch,sequence,lookuphash,1) + if ok then + done=true + success=true + end + end + end + end + local function k_run(sub,injection,last) + local a=getattr(sub,0) + if a then + a=(a==attr) and (not attribute or getprop(sub,a_state)==attribute) + else + a=not attribute or getprop(sub,a_state)==attribute + end + if a then + for n in traverse_nodes(sub) do + if n==last then + break + end + local id=getid(n) + if id==glyph_code then + local lookupmatch=lookupcache[getchar(n)] + if lookupmatch then + local h,d,ok=handler(sub,n,kind,lookupname,lookupmatch,sequence,lookuphash,1,injection) + if ok then + done=true + success=true + end end + else end end - setfield(prev,"next",disc) end - return next end while start do local id=getid(start) if id==glyph_code then - if getfont(start)==font and getsubtype(start)<256 then + if getfont(start)==font and getsubtype(start)<256 then local a=getattr(start,0) if a then a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) @@ -9407,13 +10564,18 @@ local function featuresprocessor(head,font,attr) a=not attribute or getprop(start,a_state)==attribute end if a then - local lookupmatch=lookupcache[getchar(start)] + local char=getchar(start) + local lookupmatch=lookupcache[char] if lookupmatch then local ok - head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) + head,start,ok=handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,1) if ok then success=true + elseif gpossing and zwnjruns and char==zwnj then + discrun(start,d_run) end + elseif gpossing and zwnjruns and char==zwnj then + discrun(start,d_run) end if start then start=getnext(start) end else @@ -9423,62 +10585,15 @@ local function featuresprocessor(head,font,attr) start=getnext(start) end elseif id==disc_code then - if getsubtype(start)==discretionary_code then - local pre=getfield(start,"pre") - if pre then - local new=subrun(pre) - if new then setfield(start,"pre",new) end - end - local post=getfield(start,"post") - if post then - local new=subrun(post) - if new then setfield(start,"post",new) end - end - local replace=getfield(start,"replace") - if replace then - local new=subrun(replace) - if new then setfield(start,"replace",new) end - end -elseif typ=="gpos_single" or typ=="gpos_pair" then - kerndisc(start) - end - start=getnext(start) - elseif id==whatsit_code then - local subtype=getsubtype(start) - if subtype==dir_code then - local dir=getfield(start,"dir") - if dir=="+TRT" or dir=="+TLT" then - topstack=topstack+1 - dirstack[topstack]=dir - elseif dir=="-TRT" or dir=="-TLT" then - topstack=topstack-1 - end - local newdir=dirstack[topstack] - if newdir=="+TRT" then - rlmode=-1 - elseif newdir=="+TLT" then - rlmode=1 - else - rlmode=rlparmode - end - if trace_directions then - report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) - end - elseif subtype==localpar_code then - local dir=getfield(start,"dir") - if dir=="TRT" then - rlparmode=-1 - elseif dir=="TLT" then - rlparmode=1 - else - rlparmode=0 - end - rlmode=rlparmode - if trace_directions then - report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) - end + if gpossing then + kernrun(start,k_run) + start=getnext(start) + elseif typ=="gsub_ligature" then + start=testrun(start,t_run,c_run) + else + comprun(start,c_run) + start=getnext(start) end - start=getnext(start) elseif id==math_code then start=getnext(end_of_math(start)) else @@ -9487,12 +10602,19 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then end end else - local function subrun(start) - local head=start + local function c_run(head) local done=false + local start=sweephead[head] + if start then + sweephead[head]=nil + else + start=head + end while start do local id=getid(start) - if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then + if id~=glyph_code then + start=getnext(start) + elseif getfont(start)==font and getsubtype(start)<256 then local a=getattr(start,0) if a then a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) @@ -9500,14 +10622,15 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then a=not attribute or getprop(start,a_state)==attribute end if a then + local char=getchar(start) for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local lookupmatch=lookupcache[char] if lookupmatch then local ok - head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + head,start,ok=handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,i) if ok then done=true break @@ -9524,46 +10647,120 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then start=getnext(start) end else - start=getnext(start) + return head,false end end if done then success=true - return head end + return head,done end - local function kerndisc(disc) - local prev=getprev(disc) - local next=getnext(disc) - if prev and next then - setfield(prev,"next",next) - local a=getattr(prev,0) - if a then - a=(a==attr) and (not attribute or getprop(prev,a_state)==attribute) - else - a=not attribute or getprop(prev,a_state)==attribute + local function d_run(prev) + local a=getattr(prev,0) + if a then + a=(a==attr) and (not attribute or getprop(prev,a_state)==attribute) + else + a=not attribute or getprop(prev,a_state)==attribute + end + if a then + local char=getchar(prev) + for i=1,ns do + local lookupname=subtables[i] + local lookupcache=lookuphash[lookupname] + if lookupcache then + local lookupmatch=lookupcache[char] + if lookupmatch then + local h,d,ok=handler(head,prev,kind,lookupname,lookupmatch,sequence,lookuphash,i) + if ok then + done=true + break + end + end + else + report_missing_cache(typ,lookupname) + end end - if a then - for i=1,ns do - local lookupname=subtables[i] - local lookupcache=lookuphash[lookupname] - if lookupcache then - local lookupmatch=lookupcache[getchar(prev)] - if lookupmatch then - local h,d,ok=handler(head,prev,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) - if ok then - done=true - break + end + end + local function k_run(sub,injection,last) + local a=getattr(sub,0) + if a then + a=(a==attr) and (not attribute or getprop(sub,a_state)==attribute) + else + a=not attribute or getprop(sub,a_state)==attribute + end + if a then + for n in traverse_nodes(sub) do + if n==last then + break + end + local id=getid(n) + if id==glyph_code then + local char=getchar(n) + for i=1,ns do + local lookupname=subtables[i] + local lookupcache=lookuphash[lookupname] + if lookupcache then + local lookupmatch=lookupcache[char] + if lookupmatch then + local h,d,ok=handler(head,n,kind,lookupname,lookupmatch,sequence,lookuphash,i,injection) + if ok then + done=true + break + end end + else + report_missing_cache(typ,lookupname) end - else - report_missing_cache(typ,lookupname) end + else end end - setfield(prev,"next",disc) end - return next + end + local function t_run(start,stop) + while start~=stop do + local id=getid(start) + if id==glyph_code and getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) + if a then + a=(a==attr) and (not attribute or getprop(start,a_state)==attribute) + else + a=not attribute or getprop(start,a_state)==attribute + end + if a then + local char=getchar(start) + for i=1,ns do + local lookupname=subtables[i] + local lookupcache=lookuphash[lookupname] + if lookupcache then + local lookupmatch=lookupcache[char] + if lookupmatch then + local s=getnext(start) + local l=nil + while s do + local lg=lookupmatch[getchar(s)] + if lg then + l=lg + s=getnext(s) + else + break + end + end + if l and l.ligature then + return true + end + end + else + report_missing_cache(typ,lookupname) + end + end + end + start=getnext(start) + else + break + end + end end while start do local id=getid(start) @@ -9580,16 +10777,21 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[getchar(start)] + local char=getchar(start) + local lookupmatch=lookupcache[char] if lookupmatch then local ok - head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) + head,start,ok=handler(head,start,kind,lookupname,lookupmatch,sequence,lookuphash,i) if ok then success=true break elseif not start then break + elseif gpossing and zwnjruns and char==zwnj then + discrun(start,d_run) end + elseif gpossing and zwnjruns and char==zwnj then + discrun(start,d_run) end else report_missing_cache(typ,lookupname) @@ -9603,62 +10805,15 @@ elseif typ=="gpos_single" or typ=="gpos_pair" then start=getnext(start) end elseif id==disc_code then - if getsubtype(start)==discretionary_code then - local pre=getfield(start,"pre") - if pre then - local new=subrun(pre) - if new then setfield(start,"pre",new) end - end - local post=getfield(start,"post") - if post then - local new=subrun(post) - if new then setfield(start,"post",new) end - end - local replace=getfield(start,"replace") - if replace then - local new=subrun(replace) - if new then setfield(start,"replace",new) end - end -elseif typ=="gpos_single" or typ=="gpos_pair" then - kerndisc(start) - end - start=getnext(start) - elseif id==whatsit_code then - local subtype=getsubtype(start) - if subtype==dir_code then - local dir=getfield(start,"dir") - if dir=="+TRT" or dir=="+TLT" then - topstack=topstack+1 - dirstack[topstack]=dir - elseif dir=="-TRT" or dir=="-TLT" then - topstack=topstack-1 - end - local newdir=dirstack[topstack] - if newdir=="+TRT" then - rlmode=-1 - elseif newdir=="+TLT" then - rlmode=1 - else - rlmode=rlparmode - end - if trace_directions then - report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) - end - elseif subtype==localpar_code then - local dir=getfield(start,"dir") - if dir=="TRT" then - rlparmode=-1 - elseif dir=="TLT" then - rlparmode=1 - else - rlparmode=0 - end - rlmode=rlparmode - if trace_directions then - report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) - end + if gpossing then + kernrun(start,k_run) + start=getnext(start) + elseif typ=="gsub_ligature" then + start=testrun(start,t_run,c_run) + else + comprun(start,c_run) + start=getnext(start) end - start=getnext(start) elseif id==math_code then start=getnext(end_of_math(start)) else @@ -9685,43 +10840,46 @@ local function generic(lookupdata,lookupname,unicode,lookuphash) lookuphash[lookupname]={ [unicode]=lookupdata } end end +local function ligature(lookupdata,lookupname,unicode,lookuphash) + local target=lookuphash[lookupname] + if not target then + target={} + lookuphash[lookupname]=target + end + for i=1,#lookupdata do + local li=lookupdata[i] + local tu=target[li] + if not tu then + tu={} + target[li]=tu + end + target=tu + end + target.ligature=unicode +end +local function pair(lookupdata,lookupname,unicode,lookuphash) + local target=lookuphash[lookupname] + if not target then + target={} + lookuphash[lookupname]=target + end + local others=target[unicode] + local paired=lookupdata[1] + if others then + others[paired]=lookupdata + else + others={ [paired]=lookupdata } + target[unicode]=others + end +end local action={ substitution=generic, multiple=generic, alternate=generic, position=generic, - ligature=function(lookupdata,lookupname,unicode,lookuphash) - local target=lookuphash[lookupname] - if not target then - target={} - lookuphash[lookupname]=target - end - for i=1,#lookupdata do - local li=lookupdata[i] - local tu=target[li] - if not tu then - tu={} - target[li]=tu - end - target=tu - end - target.ligature=unicode - end, - pair=function(lookupdata,lookupname,unicode,lookuphash) - local target=lookuphash[lookupname] - if not target then - target={} - lookuphash[lookupname]=target - end - local others=target[unicode] - local paired=lookupdata[1] - if others then - others[paired]=lookupdata - else - others={ [paired]=lookupdata } - target[unicode]=others - end - end, + ligature=ligature, + pair=pair, + kern=pair, } local function prepare_lookups(tfmdata) local rawdata=tfmdata.shared.rawdata @@ -9732,13 +10890,14 @@ local function prepare_lookups(tfmdata) local lookuptypes=resources.lookuptypes local characters=tfmdata.characters local descriptions=tfmdata.descriptions + local duplicates=resources.duplicates for unicode,character in next,characters do local description=descriptions[unicode] if description then local lookups=description.slookups if lookups then for lookupname,lookupdata in next,lookups do - action[lookuptypes[lookupname]](lookupdata,lookupname,unicode,lookuphash) + action[lookuptypes[lookupname]](lookupdata,lookupname,unicode,lookuphash,duplicates) end end local lookups=description.mlookups @@ -9747,7 +10906,7 @@ local function prepare_lookups(tfmdata) local lookuptype=lookuptypes[lookupname] for l=1,#lookuplist do local lookupdata=lookuplist[l] - action[lookuptype](lookupdata,lookupname,unicode,lookuphash) + action[lookuptype](lookupdata,lookupname,unicode,lookuphash,duplicates) end end end @@ -9769,7 +10928,7 @@ local function prepare_lookups(tfmdata) for name,anchor in next,anchors do local lookups=anchor_to_lookup[name] if lookups then - for lookup,_ in next,lookups do + for lookup in next,lookups do local target=lookuphash[lookup] if target then target[unicode]=anchors @@ -9851,7 +11010,7 @@ local function prepare_contextchains(tfmdata) if sequence[1] then nt=nt+1 t[nt]={ nofrules,lookuptype,sequence,start,stop,rule.lookups,replacements } - for unic,_ in next,sequence[start] do + for unic in next,sequence[start] do local cu=contexts[unic] if not cu then contexts[unic]=t @@ -9899,9 +11058,10 @@ registerotffeature { } otf.handlers=handlers -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-otn”] --- -do -- begin closure to overcome local limits and interference + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-otp” 18b4375155925ee1809150f4f6c3973b] --- if not modules then modules={} end modules ['font-otp']={ version=1.001, @@ -9910,9 +11070,8 @@ if not modules then modules={} end modules ['font-otp']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local next,type=next,type +local next,type,tostring=next,type,tostring local sort,concat=table.sort,table.concat -local sortedhash=table.sortedhash local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end) local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) local report_otf=logs.reporter("fonts","otf loading") @@ -10737,9 +11896,10 @@ end otf.enhancers.unpack=unpackdata otf.enhancers.pack=packdata -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-otp”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-lua” 50b8edb1db7009b6c661ab71ff24a466] --- if not modules then modules={} end modules ['luatex-fonts-lua']={ version=1.001, @@ -10772,9 +11932,10 @@ function fonts.readers.lua(specification) end end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-lua”] --- -do -- begin closure to overcome local limits and interference + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “font-def” 3c71c27300a8cb5c29f5d278d2049fb6] --- if not modules then modules={} end modules ['font-def']={ version=1.001, @@ -10888,10 +12049,11 @@ end function resolvers.name(specification) local resolve=fonts.names.resolve if resolve then - local resolved,sub=resolve(specification.name,specification.sub,specification) + local resolved,sub,subindex=resolve(specification.name,specification.sub,specification) if resolved then specification.resolved=resolved specification.sub=sub + specification.subindex=subindex local suffix=lower(suffixonly(resolved)) if fonts.formats[suffix] then specification.forced=suffix @@ -10908,10 +12070,11 @@ end function resolvers.spec(specification) local resolvespec=fonts.names.resolvespec if resolvespec then - local resolved,sub=resolvespec(specification.name,specification.sub,specification) + local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification) if resolved then specification.resolved=resolved specification.sub=sub + specification.subindex=subindex specification.forced=lower(suffixonly(resolved)) specification.forcedname=resolved specification.name=removesuffix(resolved) @@ -11103,9 +12266,10 @@ function font.getfont(id) end callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “font-def”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-def” 8dc05f2aa96d2fd0245242c8fd3320eb] --- if not modules then modules={} end modules ['luatex-font-def']={ version=1.001, @@ -11185,9 +12349,10 @@ function fonts.definers.applypostprocessors(tfmdata) return tfmdata end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-def”] --- -do -- begin closure to overcome local limits and interference + +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-ext” 0eee87fb26b7d135da88ac0a43a8037a] --- if not modules then modules={} end modules ['luatex-fonts-ext']={ version=1.001, @@ -11404,9 +12569,10 @@ otffeatures.register { } } -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-ext”] --- + -do -- begin closure to overcome local limits and interference +do --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-cbk” 3e86c6a492ca8d792f6b06149ba0dd57] --- if not modules then modules={} end modules ['luatex-fonts-cbk']={ version=1.001, @@ -11422,6 +12588,8 @@ end local fonts=fonts local nodes=nodes local traverse_id=node.traverse_id +local free_node=node.free +local remove_node=node.remove local glyph_code=nodes.nodecodes.glyph local disc_code=nodes.nodecodes.disc local ligaturing=node.ligaturing @@ -11451,6 +12619,8 @@ function nodes.handlers.nodepass(head) local basefonts={} local prevfont=nil local basefont=nil + local variants=nil + local redundant=nil for n in traverse_id(glyph_code,head) do local font=n.font if font~=prevfont then @@ -11472,10 +12642,47 @@ function nodes.handlers.nodepass(head) basefonts[#basefonts+1]=basefont end end + local resources=tfmdata.resources + variants=resources and resources.variants + variants=variants and next(variants) and variants or false + end + else + local tfmdata=fontdata[prevfont] + if tfmdata then + local resources=tfmdata.resources + variants=resources and resources.variants + variants=variants and next(variants) and variants or false + end + end + end + if variants then + local char=n.char + if char>=0xFE00 and (char<=0xFE0F or (char>=0xE0100 and char<=0xE01EF)) then + local hash=variants[char] + if hash then + local p=n.prev + if p and p.id==glyph_code then + local variant=hash[p.char] + if variant then + p.char=variant + if not redundant then + redundant={ n } + else + redundant[#redundant+1]=n + end + end + end end end end end + if redundant then + for i=1,#redundant do + local n=redundant[i] + remove_node(head,n) + free_node(n) + end + end for d in traverse_id(disc_code,head) do local r=d.replace if r then @@ -11512,12 +12719,30 @@ function nodes.handlers.nodepass(head) local range=basefonts[i] local start=range[1] local stop=range[2] - if stop then - start,stop=ligaturing(start,stop) - start,stop=kerning(start,stop) - elseif start then - start=ligaturing(start) - start=kerning(start) + if start or stop then + local prev=nil + local next=nil + local front=start==head + if stop then + next=stop.next + start,stop=ligaturing(start,stop) + start,stop=kerning(start,stop) + elseif start then + prev=start.prev + start=ligaturing(start) + start=kerning(start) + end + if prev then + start.prev=prev + prev.next=start + end + if next then + stop.next=next + next.prev=stop + end + if front then + head=start + end end end end @@ -11527,7 +12752,7 @@ function nodes.handlers.nodepass(head) end end function nodes.handlers.basepass(head) - if not basepass then + if basepass then head=ligaturing(head) head=kerning(head) end @@ -11549,4 +12774,7 @@ function nodes.simple_font_handler(head) end end -end -- closure +end --- [luaotfload, fontloader-2015-12-12.lua scope for “fonts-cbk”] --- + + +--- vim:ft=lua:sw=2:ts=8:et:tw=79 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-package.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-package.lua deleted file mode 100644 index 524dbcb05e8..00000000000 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-package.lua +++ /dev/null @@ -1,99 +0,0 @@ --- ------------------------------------------------------------------------ --- FILE: luaotfload-package.lua --- DESCRIPTION: Luatex fontloader packaging --- REQUIREMENTS: luatex, mtx-package --- AUTHOR: Philipp Gesang --- LICENSE: GNU GPL v2.0 ------------------------------------------------------------------------ --- - ---- The original initialization sequence by Hans Hagen, see the file ---- luatex-fonts.lua for details: ---- ---- [01] l-lua.lua ---- [02] l-lpeg.lua ---- [03] l-function.lua ---- [04] l-string.lua ---- [05] l-table.lua ---- [06] l-io.lua ---- [07] l-file.lua ---- [08] l-boolean.lua ---- [09] l-math.lua ---- [10] util-str.lua ---- [11] luatex-basics-gen.lua ---- [12] data-con.lua ---- [13] luatex-basics-nod.lua ---- [14] font-ini.lua ---- [15] font-con.lua ---- [16] luatex-fonts-enc.lua ---- [17] font-cid.lua ---- [18] font-map.lua ---- [19] luatex-fonts-syn.lua ---- [20] font-tfm.lua ---- [21] font-afm.lua ---- [22] font-afk.lua ---- [23] luatex-fonts-tfm.lua ---- [24] font-oti.lua ---- [25] font-otf.lua ---- [26] font-otb.lua ---- [27] luatex-fonts-inj.lua ---- [28] luatex-fonts-ota.lua ---- [29] luatex-fonts-otn.lua ---- [30] font-otp.lua ---- [31] luatex-fonts-lua.lua ---- [32] font-def.lua ---- [33] luatex-fonts-def.lua ---- [34] luatex-fonts-ext.lua ---- [35] luatex-fonts-cbk.lua ---- ---- Of these, nos. 01--10 are provided by the Lualibs. Keeping them ---- around in the Luaotfload fontloader is therefore unnecessary. ---- Packaging needs to account for this difference. - -loadmodule "l-lua.lua" -loadmodule "l-lpeg.lua" -loadmodule "l-function.lua" -loadmodule "l-string.lua" -loadmodule "l-table.lua" -loadmodule "l-io.lua" -loadmodule "l-file.lua" -loadmodule "l-boolean.lua" -loadmodule "l-math.lua" -loadmodule "util-str.lua" - ---- Another file containing auxiliary definitions must be present ---- prior to initialization of the configuration. - -loadmodule "luatex-basics-gen.lua" - ---- The files below constitute the “fontloader proper”. Some of the ---- functionality like file resolvers is overloaded later by ---- Luaotfload. Consequently, the resulting package is pretty ---- bare-bones and not usable independently. - -loadmodule("data-con.lua") -loadmodule("luatex-basics-nod.lua") -loadmodule("font-ini.lua") -loadmodule("font-con.lua") -loadmodule("luatex-fonts-enc.lua") -loadmodule("font-cid.lua") -loadmodule("font-map.lua") -loadmodule("luatex-fonts-syn.lua") -loadmodule("font-tfm.lua") -loadmodule("font-afm.lua") -loadmodule("font-afk.lua") -loadmodule("luatex-fonts-tfm.lua") -loadmodule("font-oti.lua") -loadmodule("font-otf.lua") -loadmodule("font-otb.lua") -loadmodule("luatex-fonts-inj.lua") -loadmodule("luatex-fonts-ota.lua") -loadmodule("luatex-fonts-otn.lua") -loadmodule("font-otp.lua") -loadmodule("luatex-fonts-lua.lua") -loadmodule("font-def.lua") -loadmodule("luatex-fonts-def.lua") -loadmodule("luatex-fonts-ext.lua") -loadmodule("luatex-fonts-cbk.lua") - diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua index 94dc1fd75b9..34a206312a9 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua @@ -1,6 +1,6 @@ return { ["hashes"]={ - { "fontloader-2015-12-09.lua", "76f5af1071a3fd169f0a80704a6a5f5e" }, + { "fontloader-2015-12-12.lua", "bcc0cb6536e04a9ee4693848a505d568" }, { "fontloader-util-str.lua", "cc6f38cc53aff51d60e2223bf922bb0d" }, { "fontloader-swiglib-test.lua", "c1cdeff07e5b8896f7aa98ce50c31618" }, { "fontloader-swiglib.lua", "3a350d89416637073b7f09e281dc7c11" }, @@ -46,10 +46,9 @@ return { { "fontloader-tl2014.lua", "5bce3c40d6841694d6be5ad3680d5b10" }, { "fontloader-reference.lua", "f3481efe06dc45db0dc7404aa96754e3" }, { "fontloader-basics-gen.lua", "aa7229a3a0ae35d19bbe46e71d65bd2c" }, - { "luaotfload-package.lua", "dcc2311200ba2b0efa2ac76b152b9720" }, { "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" }, - { "mkstatus", "fcc6c1817169a64cdf8b0ef48bec36a2" }, - { "mkimport", "8c94dde3cfe04864e1785e6fc8bebc96" }, + { "mkstatus", "76308532fa0175ac046e6ed1bf11e4b8" }, + { "mkimport", "988e04fc571b2984eb21894cf0ea76e5" }, { "mkglyphlist", "0acaf0fbc9dce6fda4e717a7ddcfdef6" }, { "mkcharacters", "5274a32b25f2dc1f55e75546c551035e" }, { "luaotfload-glyphlist.lua", "ff440162d1b8a78a586375ee65630c21" }, @@ -71,8 +70,9 @@ return { }, ["notes"]={ ["committer"]="Philipp Gesang <phg@phi-gamma.net>", - ["loader"]="fontloader-2015-12-09.lua", - ["revision"]="656e7a115ab7c87743be59808713908f1d22fa6c", - ["timestamp"]="2015-12-09 23:02:31 +0100", + ["description"]="v2.6-fix-2", + ["loader"]="fontloader-2015-12-12.lua", + ["revision"]="2fdaee0d9a2687e99b1f44be15b6876be22a495b", + ["timestamp"]="2015-12-12 20:05:29 +0100", }, }
\ No newline at end of file |