summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile20
-rw-r--r--NEWS3
-rw-r--r--doc/filegraph.dot3
-rwxr-xr-x[-rw-r--r--]scripts/mkimport152
-rwxr-xr-xscripts/mkstatus62
-rw-r--r--src/fontloader/luaotfload-package.lua6
-rw-r--r--src/fontloader/runtime/fontloader-reference.lua (renamed from src/fontloader/runtime/fontloader-fontloader.lua)0
-rw-r--r--src/luaotfload-colors.lua17
-rw-r--r--src/luaotfload-configuration.lua6
-rw-r--r--src/luaotfload-database.lua110
-rw-r--r--src/luaotfload-init.lua140
-rw-r--r--src/luaotfload-letterspace.lua9
-rw-r--r--src/luaotfload-log.lua49
-rw-r--r--src/luaotfload-main.lua246
-rw-r--r--src/luaotfload-override.lua52
-rw-r--r--src/luaotfload-resolvers.lua256
16 files changed, 666 insertions, 465 deletions
diff --git a/Makefile b/Makefile
index ab5c464..bd0021b 100644
--- a/Makefile
+++ b/Makefile
@@ -6,6 +6,7 @@ DOCSRCDIR = ./doc
SCRIPTSRCDIR = ./scripts
SRCSRCDIR = ./src
FONTLOADERDIR = $(SRCSRCDIR)/fontloader/runtime
+PACKAGEDIR = $(SRCSRCDIR)/fontloader
BUILDDIR = ./build
MISCDIR = ./misc
@@ -48,7 +49,8 @@ DOCS = $(DOCPDF) $(DOTPDF) $(MANPAGES)
GLYPHS = $(BUILDDIR)/$(NAME)-glyphlist.lua
CHARS = $(BUILDDIR)/$(NAME)-characters.lua
STATUS = $(BUILDDIR)/$(NAME)-status.lua
-RESOURCES = $(GLYPHS) $(CHARS) $(STATUS)
+LOADER = $(BUILDDIR)/fontloader-$(shell date +%F).lua
+RESOURCES = $(GLYPHS) $(CHARS) $(LOADER) $(STATUS)
SOURCE = $(DOCSRC) $(MANSRC) $(SRC) README COPYING Makefile NEWS $(RESOURCESCRIPTS)
# Files grouped by installation location
@@ -88,8 +90,10 @@ LUA = texlua
## variables.
DO_GLYPHS = $(LUA) $(GLYPHSCRIPT) > /dev/null
DO_CHARS = $(LUA) $(CHARSCRIPT) > /dev/null
-DO_STATUS = $(LUA) $(STATUSSCRIPT) > /dev/null
-DO_IMPORT = $(LUA) $(IMPORTSCRIPT) > /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
define check-lua-files
@echo validating syntax
@@ -113,8 +117,12 @@ builddir: $(BUILDDIR)
resources: $(RESOURCES)
chars: $(CHARS)
status: $(STATUS)
+package: loader
+loader: $(LOADER)
ctan: $(CTAN_ZIP)
tds: $(TDS_ZIP)
+import:
+ $(DO_IMPORT)
graph: $(DOTPDF)
doc: $(DOCS)
@@ -136,9 +144,12 @@ $(GLYPHS): builddir
$(CHARS): builddir
$(DO_CHARS)
-$(STATUS): builddir
+$(STATUS): builddir loader
$(DO_STATUS)
+$(LOADER): builddir
+ $(DO_PACKAGE)
+
$(BUILDDIR): /dev/null
mkdir -p $(BUILDDIR)
@@ -222,6 +233,7 @@ showtargets:
@echo " luaotfload.conf(5) (requires Docutils)"
@echo " graph generate file graph (requires GraphViz)"
@echo
+ @echo " loader merge fontloader"
@echo " chars import char-def.lua as luaotfload-characters.lua"
@echo " status create repository info (luaotfload-status.lua)"
@echo
diff --git a/NEWS b/NEWS
index 7902abc..a1ffb1e 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,9 @@ Change History
* Revised letterspacing, now utilizing the ``node.direct`` interface
* Revized colorization of fonts, utilizing ``node.direct`` (Dohyun Kim)
* Colorization was moved to the ``post_linebreak_filter`` stage
+ * Move remaining functionality from ``luaotfload-override`` into
+ initialization
+ * Write names index if fonts were removed
2014/07/13, luaotfload v2.5
* Remove legacy code.
diff --git a/doc/filegraph.dot b/doc/filegraph.dot
index 47db9ea..e1a9937 100644
--- a/doc/filegraph.dot
+++ b/doc/filegraph.dot
@@ -199,10 +199,9 @@ strict digraph luaotfload_files { //looks weird with circo ...
<table cellborder="0" bgcolor="#FFFFFFAA">
<th> <td colspan="2"> <font point-size="12" face="Iwona Italic">Luaotfload Libraries</font> </td> </th>
<tr> <td>luaotfload-auxiliary.lua</td> <td>luaotfload-features.lua</td> </tr>
- <tr> <td>luaotfload-override.lua</td> <td>luaotfload-loaders.lua</td> </tr>
+ <tr> <td>luaotfload-loaders.lua</td> <td>luaotfload-color.lua</td> </tr>
<tr> <td>luaotfload-log.lua</td> <td>luaotfload-letterspace.lua</td> </tr>
<tr> <td>luaotfload-parsers.lua</td> <td>luaotfload-database.lua</td> </tr>
- <tr> <td>luaotfload-color.lua</td> </tr>
</table>
>,
]
diff --git a/scripts/mkimport b/scripts/mkimport
index a430587..0833ccb 100644..100755
--- a/scripts/mkimport
+++ b/scripts/mkimport
@@ -1,7 +1,7 @@
#!/usr/bin/env texlua
-------------------------------------------------------------------------------
-- FILE: mkimport.lua
--- USAGE: ./mkimport.lua
+-- USAGE: texlua ./mkimport.lua
-- DESCRIPTION: check luaotfload imports against Context
-- REQUIREMENTS: luatex, the lualibs package, Context MkIV
-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>
@@ -12,12 +12,15 @@
-------------------------------------------------------------------------------
--- PURPOSE
----
+---
--- - Facilitate detecting changes in the fontloader source.
--- - Assist in updating source code and (partially) automate importing.
+---
--- - Account for files in the plain fontloader distribution, alert in case of
--- additions or deletions.
----
+---
+--- - Fontloader packaging.
+---
-------------------------------------------------------------------------------
local debug = false
@@ -26,18 +29,23 @@ kpse.set_program_name "luatex"
local lfs = require "lfs"
local md5 = require "md5"
+local os = require "os"
require "lualibs"
+local filedirname = file.dirname
local fileiswritable = file.is_writable
local ioloaddata = io.loaddata
local iopopen = io.popen
local iowrite = io.write
local lfschdir = lfs.chdir
+local lfscurrentdir = lfs.currentdir
local lfsisdir = lfs.isdir
local lfsisfile = lfs.isfile
local md5sumhexa = md5.sumhexa
+local osdate = os.date
local osgettimeofday = os.gettimeofday
+local osrename = os.rename
local stringformat = string.format
local tableconcat = table.concat
@@ -71,6 +79,26 @@ local prefixes = {
fontloader = "luatex",
}
+--[[doc--
+
+ The output name is fixed so we have to deal with it but maybe we
+ can get a patch to mtx-package upstreamed in the future. In any
+ case, we are content with renaming the result for the time being.
+
+ The target name is constructed on the fly from the current date.
+ TODO It should be possible to supply a name and possibly
+ destination path on the command line.
+
+ Paths are relative to the base directory (``$PWD``).
+
+--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/"
+
-------------------------------------------------------------------------------
-- helpers
-------------------------------------------------------------------------------
@@ -169,7 +197,7 @@ local imports = {
{ name = "fonts-ext" , ours = nil , kind = kind_merged },
{ name = "fonts-inj" , ours = nil , kind = kind_merged },
{ name = "fonts-lua" , ours = nil , kind = kind_merged },
- { name = "fonts-merged" , ours = "fontloader" , kind = kind_essential },
+ { name = "fonts-merged" , ours = "reference" , kind = kind_essential },
{ name = "fonts-ota" , ours = nil , kind = kind_merged },
{ name = "fonts-otn" , ours = nil , kind = kind_merged },
{ name = "fonts" , ours = nil , kind = kind_merged },
@@ -641,6 +669,49 @@ local tell = function (arg)
return describe (target, location)
end
+local build_paths = function (argv)
+ if not argv or type (argv) ~= "table" then die "build_paths" end
+
+ 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
+
+ if #argv >= 2 then
+ local fname = argv[2]
+ local dir = filedirname (fname) .. "/"
+ if not lfsisdir (dir) then
+ die ("second argument must be point into existing directory, not “%s”",
+ argv[2])
+ end
+ base_dir = dir
+ merge_name = fname
+ output_name = dir .. loader_output_name
+ end
+
+ if #argv == 3 then
+ --- also set the target name
+ local fname = argv[3]
+ local dir = filedirname (fname)
+ if not lfsisdir (dir) then
+ die ("third argument must be point into writable directory, not “%s”",
+ argv[3])
+ end
+ target_name = fname
+ end
+
+ local ret = {
+ orig_dir = orig_dir,
+ base_dir = base_dir,
+ merge_name = merge_name,
+ target_name = target_name,
+ output_name = output_name,
+ }
+ return ret
+end
+
--[[doc--
Packaging works as follows:
@@ -659,43 +730,40 @@ end
--doc]]--
-local package = function (args)
- local t0 = osgettimeofday ()
- local orig_dir = lfs.currentdir ()
- local base_dir = orig_dir .. "/src/fontloader/"
- local merge_name = base_dir .. "luaotfload-package.lua"
- --- output name is fixed so we have to deal with it but maybe we can
- --- get a patch to mtx-package upstreamed in the future
- local output_name = base_dir .. "luaotfload-package-merged.lua"
- local target_name = stringformat ("fontloader-%s.lua",
- os.date ("%F"))
- status ("assuming fontloader source in %s", base_dir)
- status ("reading merge instructions from %s", merge_name)
- status ("writing output to %s", target_name)
+local package = function (argv)
+ local t0 = osgettimeofday ()
+ local paths = build_paths (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 (base_dir) then die ("directory %s does not exist", emphasis (base_dir )) end
- if not lfsisfile (merge_name) then die ("missing merge file at %s", emphasis (merge_name )) end
- if not fileiswritable (output_name) then die ("cannot write to %s", emphasis (output_name)) end
- if not fileiswritable (target_name) then die ("cannot write to %s", emphasis (target_name)) end
- if not lfschdir (base_dir) then die ("failed to cd into %s", emphasis (base_dir )) end
+ 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 (output_name) then
- status ("output file already exists at “%s”, unlinking", output_name)
- local ret, err = os.remove (output_name)
+ if lfsisfile (paths.output_name) then
+ status ("output file already exists at “%s”, unlinking",
+ paths.output_name)
+ local ret, err = os.remove (paths.output_name)
if ret == nil then
- if not lfschdir (orig_dir) then
- status ("warning: failed to cd retour into %s", emphasis (orig_dir))
+ if not lfschdir (paths.orig_dir) then
+ status ("warning: failed to cd retour into %s",
+ emphasis (paths.orig_dir))
end
die ("failed to remove existing merge package")
end
end
- --die ("missing merge file at %s", emphasis (merge_name )) end
+ --die ("missing merge file at %s", emphasis (paths.merge_name )) end
--- perform merge
- local cmd = { "mtxrun", "--script", "package", "--merge", merge_name }
+ local cmd = { "mtxrun", "--script", "package", "--merge", paths.merge_name }
local shl = tableconcat (cmd, " ")
status ("invoking %s as “%s”", emphasis "mtx-package", shl)
@@ -703,8 +771,9 @@ local package = function (args)
local fh = iopopen (shl, "r")
if not fh then
- if not lfschdir (orig_dir) then
- status ("warning: failed to cd retour into %s", emphasis (orig_dir))
+ if not lfschdir (paths.orig_dir) then
+ status ("warning: failed to cd retour into %s",
+ emphasis (paths.orig_dir))
end
die ("merge failed; failed to invoke mtxrun")
end
@@ -720,19 +789,34 @@ local package = function (args)
--- clean up
- if not lfschdir (orig_dir) then
- status ("warning: failed to cd retour into %s", emphasis (orig_dir))
+ if not lfschdir (paths.orig_dir) then
+ status ("warning: failed to cd retour into %s",
+ emphasis (paths.orig_dir))
end
--- check postconditions
- if not lfsisfile (output_name) then die ("merge failed; package not found at " .. output_name) end
+ if not lfsisfile (paths.output_name) then
+ die ("merge failed; package not found at " .. 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)
end
local help = function ()
diff --git a/scripts/mkstatus b/scripts/mkstatus
index e18abb7..809d4af 100755
--- a/scripts/mkstatus
+++ b/scripts/mkstatus
@@ -26,6 +26,7 @@ local iosavedata = io.savedata
local iopopen = io.popen
local iowrite = io.write
local lfsisdir = lfs.isdir
+local stringmatch = string.match
-----------------------------------------------------------------------
-- settings
@@ -55,8 +56,8 @@ local names = {
{ "src", "luaotfload-loaders.lua", },
{ "src", "luaotfload-log.lua", },
{ "src", "luaotfload-main.lua", },
- { "src/fontloader/runtime", "fontloader-fontloader.lua", },
- { "src", "luaotfload-override.lua", },
+ { "src/fontloader/runtime", "fontloader-reference.lua", },
+ --{ "src", "luaotfload-override.lua", }, --> part of init now
{ "src", "luaotfload-parsers.lua", },
{ "src", "luaotfload-tool.lua", },
{ "scripts", "mkcharacters", },
@@ -121,8 +122,9 @@ end
local hash_all
hash_all = function (list, acc)
- if list == nil then
- return hash_all (table.fastcopy (names), { })
+ if acc == nil then
+ local base = table.fastcopy (names)
+ return hash_all (table.append (base, list), { })
end
local finfo = list[#list]
@@ -156,10 +158,58 @@ hash_all = function (list, acc)
return acc
end
+local handle_argv = function (argv)
+ local ret = { files = { }, loader = nil }
+ local argc = #argv
+ if argc < 1 then return ret end
+ local argoff = 1
+ if argv [1] == "-v" then
+ verbose = true
+ if argc == 1 then return ret end
+ argoff = 2
+ end
+ local aux aux = function (acc, i)
+ if i > argc then return acc else
+ local cur = argv[i]
+ if type (cur) == "string" then
+ local loader = stringmatch (cur, "--fontloader=(.+)$")
+ if loader then
+ cur = loader
+ acc.loader = file.basename (cur)
+ end
+ if lfs.isfile (cur) then
+ local files = acc.files
+ files[#files + 1] = cur
+ end
+ else
+ die ("file not found: %s", tostring (cur))
+ end
+ return aux (acc, i + 1)
+ end
+ end
+ return aux (ret, argoff)
+end
+
+local add_files
+add_files = function (lst, acc)
+ if lst == nil then return end
+ if acc == nil then return add_files (lst, { }) end
+ local len = #lst
+ if len == 0 then return acc end
+ local cur = lst[len]
+ local fname = file.basename (cur)
+ local path = file.dirname (cur)
+ acc[#acc + 1] = { path, fname }
+ lst[len] = nil
+ return add_files (lst, acc)
+end
+
local main = function ()
- if arg [1] == "-v" then verbose = true end
- local hashes = hash_all ()
+ local raw_extra = handle_argv (arg)
+ local cuit_extra = add_files (raw_extra.files)
+ local hashes = hash_all (cuit_extra)
local notes = git_info ()
+ notes.loader = raw_extra.loader
local serialized = table.serialize ({ notes = notes,
hashes = hashes }, true)
local success = io.savedata (filelist, serialized)
diff --git a/src/fontloader/luaotfload-package.lua b/src/fontloader/luaotfload-package.lua
index b60ae17..725c498 100644
--- a/src/fontloader/luaotfload-package.lua
+++ b/src/fontloader/luaotfload-package.lua
@@ -63,12 +63,16 @@ 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("luatex-basics-gen.lua")
loadmodule("data-con.lua")
loadmodule("luatex-basics-nod.lua")
loadmodule("font-ini.lua")
diff --git a/src/fontloader/runtime/fontloader-fontloader.lua b/src/fontloader/runtime/fontloader-reference.lua
index d8095a2..d8095a2 100644
--- a/src/fontloader/runtime/fontloader-fontloader.lua
+++ b/src/fontloader/runtime/fontloader-reference.lua
diff --git a/src/luaotfload-colors.lua b/src/luaotfload-colors.lua
index 8035210..19903d8 100644
--- a/src/luaotfload-colors.lua
+++ b/src/luaotfload-colors.lua
@@ -40,6 +40,8 @@ local setattribute = nodedirect.set_attribute
local texset = tex.set
local texget = tex.get
+local texsettoks = tex.settoks
+local texgettoks = tex.gettoks
local stringformat = string.format
local concat = table.concat
@@ -310,9 +312,6 @@ node_colorize = function (head, current_color)
return head, current_color
end
-local pgf_extgs = { }
-luaotfload.pgf_extgs = pgf_extgs
-
--- node -> node
local color_handler = function (head)
head = todirect(head)
@@ -326,7 +325,7 @@ local color_handler = function (head)
local no_extgs = not tpr:find("/ExtGState<<.*>>")
local pgf_loaded = no_extgs and luaotfload.pgf_loaded
if pgf_loaded then
- tpr = concat(pgf_extgs)
+ tpr = texgettoks(pgf_loaded)
end
local t = ""
@@ -338,7 +337,7 @@ local color_handler = function (head)
end
if t ~= "" then
if pgf_loaded then
- pgf_extgs[#pgf_extgs+1] = t
+ texsettoks("global", pgf_loaded, tpr..t)
else
if no_extgs then
tpr = tpr .. "/ExtGState<<>>"
@@ -379,13 +378,5 @@ add_color_callback = function ( )
end
end
-tex.sprint("\\count255=\\catcode`@ \\catcode`@=11 ",
- "\\ifdefined\\AtBeginDocument\\else\\def\\AtBeginDocument#1{#1}\\fi",
- "\\AtBeginDocument{\\ifdefined\\pgfutil@everybye",
- "\\directlua{luaotfload.pgf_loaded=true}\\begingroup",
- "\\toks@{\\pgf@sys@addpdfresource@extgs@plain{\\directlua{tex.sprint(luaotfload.pgf_extgs)}}}",
- "\\edef\\x{\\endgroup\\noexpand\\pgfutil@everybye{\\the\\toks@\\the\\pgfutil@everybye}}\\x",
- "\\fi}\\catcode`@=\\count255 ")
-
-- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/src/luaotfload-configuration.lua b/src/luaotfload-configuration.lua
index e9393c5..e2cfbd8 100644
--- a/src/luaotfload-configuration.lua
+++ b/src/luaotfload-configuration.lua
@@ -140,9 +140,9 @@ local feature_presets = {
--doc]]--
local registered_loaders = {
- default = "fontloader",
- fontloader = "fontloader",
- tl2013 = "tl2013",
+ default = luaotfloadstatus and luaotfloadstatus.notes.loader or "reference",
+ reference = "reference",
+ tl2014 = "tl2014",
}
--[[doc--
diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua
index 1831ca3..f4aab16 100644
--- a/src/luaotfload-database.lua
+++ b/src/luaotfload-database.lua
@@ -454,22 +454,19 @@ end
--- define locals in scope
local access_font_index
local collect_families
-local font_file_lookup
local find_closest
local flush_lookup_cache
local generate_filedata
local get_font_filter
local group_modifiers
-local load_lookups
local load_names
+local lookup_font_name
local getmetadata
local order_design_sizes
local ot_fullinfo
local read_blacklist
local reload_db
-local resolve_cached
-local resolve_fullpath
-local resolve_name
+local lookup_fullpath
local save_lookups
local save_names
local set_font_filter
@@ -558,6 +555,7 @@ getmetadata = function ()
end
--- unit -> unit
+local load_lookups
load_lookups = function ( )
local foundname, data = load_lua_file(config.luaotfload.paths.lookup_path_lua)
if data then
@@ -638,7 +636,7 @@ end
--[[doc--
- font_file_lookup -- The ``file:`` are ultimately delegated here.
+ lookup_font_file -- The ``file:`` are ultimately delegated here.
The lookups are kind of a blunt instrument since they try locating
the file using every conceivable method, which is quite
inefficient. Nevertheless, resolving files that way is rarely the
@@ -647,7 +645,8 @@ end
--doc]]--
--- string -> string * string * bool
-font_file_lookup = function (filename)
+local lookup_font_file
+lookup_font_file = function (filename)
local found = lookup_filename (filename)
if not found then
@@ -667,7 +666,7 @@ font_file_lookup = function (filename)
if not fonts_reloaded and config.luaotfload.db.update_live == true then
return reload_db (stringformat ("File not found: %s.", filename),
- font_file_lookup,
+ lookup_font_file,
filename)
end
return filename, nil, false
@@ -715,7 +714,7 @@ font managment we have to check both the system path and the texmf.
--doc]]--
local verify_font_file = function (basename)
- local path = resolve_fullpath (basename)
+ local path = lookup_fullpath (basename)
if path and lfsisfile(path) then
return true
end
@@ -748,7 +747,7 @@ Idk what the “spec” resolver is for.
spec: name, sub resolved, sub, name, forced
[*] name: contains both the name resolver from luatex-fonts and
- resolve_name() below
+ lookup_font_name () below
From my reading of font-def.lua, what a resolver does is
basically rewrite the “name” field of the specification record
@@ -777,7 +776,8 @@ local hash_request = function (specification)
end
--- 'a -> 'a -> table -> (string * int|boolean * boolean)
-resolve_cached = function (specification)
+local lookup_font_name_cached
+lookup_font_name_cached = function (specification)
if not lookup_cache then load_lookups () end
local request = hash_request(specification)
report("both", 4, "cache", "Looking for %q in cache ...",
@@ -801,7 +801,7 @@ resolve_cached = function (specification)
--- case 2) cache negative ----------------------------------------
--- first we resolve normally ...
- local filename, subfont = resolve_name (specification)
+ local filename, subfont = lookup_font_name (specification)
if not filename then
return nil, nil
end
@@ -935,13 +935,13 @@ end
--[[doc--
- resolve_familyname -- Query the families table for an entry
+ lookup_familyname -- Query the families table for an entry
matching the specification.
The parameters “name” and “style” are pre-sanitized.
--doc]]--
--- spec -> string -> string -> int -> string * int
-local resolve_familyname = function (specification, name, style, askedsize)
+local lookup_familyname = function (specification, name, style, askedsize)
local families = name_index.families
local mappings = name_index.mappings
local candidates = nil
@@ -978,7 +978,7 @@ local resolve_familyname = function (specification, name, style, askedsize)
return resolved, subfont
end
-local resolve_fontname = function (specification, name, style)
+local lookup_fontname = function (specification, name, style)
local mappings = name_index.mappings
local fallback = nil
local lastresort = nil
@@ -1021,7 +1021,7 @@ end
--[[doc--
- resolve_name -- Perform a name: lookup. This first queries the
+ lookup_font_name -- Perform a name: lookup. This first queries the
font families table and, if there is no match for the spec, the
font names table.
The return value is a pair consisting of the file name and the
@@ -1059,7 +1059,7 @@ end
multiple design sizes to a given font/style combination, we put a
workaround in place that chooses that unmarked version.
- The first return value of “resolve_name” is the file name of the
+ The first return value of “lookup_font_name” is the file name of the
requested font (string). It can be passed to the fullname resolver
get_font_file().
The second value is either “false” or an integer indicating the
@@ -1068,7 +1068,7 @@ end
--doc]]--
--- table -> string * (int | bool)
-resolve_name = function (specification)
+lookup_font_name = function (specification)
local resolved, subfont
if not name_index then name_index = load_names () end
local name = sanitize_fontname (specification.name)
@@ -1086,28 +1086,28 @@ resolve_name = function (specification)
end
end
- resolved, subfont = resolve_familyname (specification,
- name,
- style,
- askedsize)
+ resolved, subfont = lookup_familyname (specification,
+ name,
+ style,
+ askedsize)
if not resolved then
- resolved, subfont = resolve_fontname (specification,
- name,
- style)
+ resolved, subfont = lookup_fontname (specification,
+ name,
+ style)
end
if not resolved then
if not fonts_reloaded and config.luaotfload.db.update_live == true then
return reload_db (stringformat ("Font %s not found.",
specification.name or "<?>"),
- resolve_name,
+ lookup_font_name,
specification)
end
end
return resolved, subfont
end
-resolve_fullpath = function (fontname, ext) --- getfilename()
+lookup_fullpath = function (fontname, ext) --- getfilename()
if not name_index then name_index = load_names () end
local files = name_index.files
local basedata = files.base
@@ -2241,6 +2241,28 @@ end
--[[doc--
+ count_removed -- Count paths that do not exist in the file system.
+
+--doc]]--
+
+--- string list -> size_t
+local count_removed = function (old)
+ report("log", 4, "db", "Checking removed files.")
+ local nrem = 0
+ local nold = #old
+ for i = 1, nold do
+ local f = old[i]
+ if not kpsereadable_file (f) then
+ report("log", 2, "db",
+ "File %s does not exist in file system.")
+ nrem = nrem + 1
+ end
+ end
+ return nrem
+end
+
+--[[doc--
+
retrieve_namedata -- Scan the list of collected fonts and populate
the list of namedata.
@@ -2253,7 +2275,7 @@ end
--doc]]--
---- string * string list -> dbobj -> dbobj -> bool? -> int
+--- string * string list -> dbobj -> dbobj -> bool? -> int * int
local retrieve_namedata = function (files, currentnames, targetnames, dry_run)
local nfiles = #files
@@ -2348,10 +2370,7 @@ local collect_font_filenames_local = function ()
return files
end
---- dbobj -> dbobj -> int * int
-
--- fontentry list -> filemap
-
generate_filedata = function (mappings)
report ("both", 2, "db", "Creating filename map.")
@@ -2383,7 +2402,6 @@ generate_filedata = function (mappings)
for index = 1, nmappings do
local entry = mappings [index]
-
local filedata = entry.file
local format
local location
@@ -2473,7 +2491,7 @@ generate_filedata = function (mappings)
--- 3) add to fullpath map
full [index] = fullpath
- end
+ end --- mapping traversal
return files
end
@@ -2849,7 +2867,7 @@ end
--doc]]--
---- unit -> string * bool list
+--- unit -> string * string list
local collect_font_filenames = function ()
report ("info", 4, "db", "Scanning the filesystem for font files.")
@@ -3098,6 +3116,8 @@ end
--- dbobj? -> bool? -> bool? -> dbobj
update_names = function (currentnames, force, dry_run)
local targetnames
+ local n_new = 0
+ local n_rem = 0
local conf = config.luaotfload
if conf.run.live ~= false and conf.db.update_live == false then
@@ -3149,13 +3169,16 @@ update_names = function (currentnames, force, dry_run)
--- pass 2: read font files (normal case) or reuse information
--- present in index
+ n_rem = count_removed (currentnames.files.full)
+
n_new = retrieve_namedata (font_filenames,
currentnames,
targetnames,
dry_run)
+
report ("info", 3, "db",
- "Found %d font files; %d new entries.",
- #font_filenames, n_new)
+ "Found %d font files; %d new, %d stale entries.",
+ #font_filenames, n_new, n_rem)
end
--- pass 3 (optional): collect some stats about the raw font info
@@ -3181,7 +3204,6 @@ update_names = function (currentnames, force, dry_run)
--- pass 7: order design size tables
targetnames.families = order_design_sizes (targetnames.families)
-
report ("info", 3, "db",
"Rebuilt in %0.f ms.",
1000 * (osgettimeofday () - starttime))
@@ -3189,8 +3211,9 @@ update_names = function (currentnames, force, dry_run)
if dry_run ~= true then
- if n_new == 0 then
- report ("info", 2, "db", "No new fonts found, skip saving to disk.")
+ if n_new + n_rem == 0 then
+ report ("info", 2, "db",
+ "No new or removed fonts, skip saving to disk.")
else
local success, reason = save_names ()
if not success then
@@ -3449,17 +3472,18 @@ names.access_font_index = access_font_index
names.data = function () return name_index end
names.save = save_names
names.update = update_names
-names.font_file_lookup = font_file_lookup
+names.lookup_font_file = lookup_font_file
+names.lookup_font_name = lookup_font_name
+names.lookup_font_name_cached = lookup_font_name_cached
+names.getfilename = lookup_fullpath
+names.lookup_fullpath = lookup_fullpath
names.read_blacklist = read_blacklist
names.sanitize_fontname = sanitize_fontname
-names.getfilename = resolve_fullpath
names.getmetadata = getmetadata
names.set_location_precedence = set_location_precedence
names.count_font_files = count_font_files
names.nth_font_filename = nth_font_filename
names.font_slice = font_slice
-names.resolve_cached = resolve_cached
-names.resolve_name = resolve_name
--- font cache
names.purge_cache = purge_cache
diff --git a/src/luaotfload-init.lua b/src/luaotfload-init.lua
index feff4cc..a493cc1 100644
--- a/src/luaotfload-init.lua
+++ b/src/luaotfload-init.lua
@@ -9,6 +9,8 @@
-----------------------------------------------------------------------
--
+local setmetatable = setmetatable
+
--[[doc--
Initialization phases:
@@ -65,7 +67,7 @@ local logreport --- filled in after loading the log module
--doc]]--
-local init_pre = function ()
+local init_early = function ()
local store = { }
config = config or { } --- global
@@ -74,6 +76,7 @@ local init_pre = function ()
config.lualibs.verbose = false
config.lualibs.prefer_merged = true
config.lualibs.load_extended = true
+ fonts = fonts or { }
require "lualibs"
@@ -131,8 +134,10 @@ local init_pre = function ()
return number
end
+ luaotfload.loaders.fontloader "basics-gen"
+
return store
-end --- [init_pre]
+end --- [init_early]
--[[doc--
@@ -180,11 +185,8 @@ end
local init_adapt = function ()
- luaotfload.context_environment = { }
- luaotfload.push_namespaces = push_namespaces
- luaotfload.pop_namespaces = pop_namespaces
-
- local our_environment = push_namespaces ()
+ local context_environment = { }
+ local our_environment = push_namespaces ()
--[[doc--
@@ -196,7 +198,7 @@ local init_adapt = function ()
tex.attribute[0] = 0
- return our_environment
+ return our_environment, context_environment
end --- [init_adapt]
@@ -277,9 +279,9 @@ local init_cleanup = function (store)
--doc]]--
- luaotfload.pop_namespaces (store.our_environment,
- false,
- luaotfload.context_environment)
+ pop_namespaces (store.our_environment,
+ false,
+ store.context_environment)
--[[doc--
@@ -294,10 +296,7 @@ local init_cleanup = function (store)
callback.register = store.trapped_register
end --- [init_cleanup]
-local init_post = function ()
- --- hook for actions that need to take place after the fontloader is
- --- installed
-
+local init_post_install_callbacks = function ()
--[[doc--
we do our own callback handling with the means provided by
@@ -316,19 +315,122 @@ local init_post = function ()
nodes.simple_font_handler,
"luaotfload.node_processor",
1)
+end
+
+local init_post_load_agl = function ()
+
+ --[[doc--
+
+ Adobe Glyph List.
+ -----------------------------------------------------------------
+
+ Context provides a somewhat different font-age.lua from an
+ unclear origin. Unfortunately, the file name it reads from is
+ hard-coded in font-enc.lua, so we have to replace the entire
+ table.
+
+ This shouldn’t cause any complications. Due to its implementation
+ the glyph list will be loaded upon loading a OTF or TTF for the
+ first time during a TeX run. (If one sticks to TFM/OFM then it is
+ never read at all.) For this reason we can install a metatable
+ that looks up the file of our choosing and only falls back to the
+ Context one in case it cannot be found.
+
+ --doc]]--
+
+ local findfile = resolvers.findfile
+ local encodings = fonts.encodings
+
+ if not findfile or not encodings then
+ --- Might happen during refactoring; we continue graciously but in
+ --- a somewhat defect state.
+ logreport ("log", 0, "init",
+ "preconditions unmet, skipping the Adobe Glyph List; "
+ .. "this is a Luaotfload bug.")
+ return
+ end
+
+ if next (fonts.encodings.agl) then
+ --- unnecessary because the file shouldn’t be loaded at this time
+ --- but we’re just making sure
+ fonts.encodings.agl = nil
+ collectgarbage"collect"
+ end
+
+ local agl_init = { } --- start out empty, fill on demand
+ encodings.agl = agl_init --- ugh, replaced again later
+
+ setmetatable (agl_init, { __index = function (t, k)
+
+ if k ~= "unicodes" then
+ return nil
+ end
+
+ local glyphlist = findfile "luaotfload-glyphlist.lua"
+ if glyphlist then
+ logreport ("log", 1, "init", "loading the Adobe glyph list")
+ else
+ glyphlist = findfile "font-age.lua"
+ logreport ("both", 0, "init",
+ "loading the extended glyph list from ConTeXt")
+ end
+
+ if not glyphlist then
+ logreport ("both", 4, "init",
+ "Adobe glyph list not found, please check your installation.")
+ return nil
+ end
+ logreport ("both", 4, "init",
+ "found Adobe glyph list file at ``%s``, using that.",
+ glyphlist)
+
+ local unicodes = dofile(glyphlist)
+ encodings.agl = { unicodes = unicodes }
+ return unicodes
+ end })
+
+end
+
+--- (unit -> unit) list
+local init_post_actions = {
+ init_post_install_callbacks,
+ init_post_load_agl,
+}
+
+--- unit -> size_t
+local init_post = function ()
+ --- hook for actions that need to take place after the fontloader is
+ --- installed
+
+ local n = #init_post_actions
+ for i = 1, n do
+ local action = init_post_actions[i]
+ local taction = type (action)
+ if not action or taction ~= "function" then
+ logreport ("both", 1, "init",
+ "post hook WARNING: action %d not a function but %s/%s; ignoring.",
+ i, action, taction)
+ else
+ --- call closure
+ action ()
+ end
+ end
+
+ return n
end --- [init_post]
return {
- init = function ()
+ early = init_early,
+ main = function (store)
local starttime = os.gettimeofday ()
- local store = init_pre ()
- store.our_environment = init_adapt ()
+ store.our_environment, store.context_environment = init_adapt ()
init_main ()
init_cleanup (store)
logreport ("both", 1, "init",
"fontloader loaded in %0.3f seconds",
os.gettimeofday() - starttime)
- init_post ()
+ local n = init_post ()
+ logreport ("both", 5, "init", "post hook terminated, %d actions performed", n)
end
}
diff --git a/src/luaotfload-letterspace.lua b/src/luaotfload-letterspace.lua
index 8956f82..9a0646b 100644
--- a/src/luaotfload-letterspace.lua
+++ b/src/luaotfload-letterspace.lua
@@ -471,12 +471,15 @@ local enablefontkerning = function ( )
local handler = function (hd)
local direct_hd = todirect (hd)
- local hd, _done = kerncharacters (hd)
- if not hd then --- bad
+ logreport ("term", 5, "letterspace",
+ "kerncharacters() invoked with node.direct interface \z
+ (``%s`` -> ``%s``)", tostring (hd), tostring (direct_hd))
+ local direct_hd, _done = kerncharacters (direct_hd)
+ if not direct_hd then --- bad
logreport ("both", 0, "letterspace",
"kerncharacters() failed to return a valid new head")
end
- return tonode (hd)
+ return tonode (direct_hd)
end
return add_processor( handler
diff --git a/src/luaotfload-log.lua b/src/luaotfload-log.lua
index a0e78bd..7c012f4 100644
--- a/src/luaotfload-log.lua
+++ b/src/luaotfload-log.lua
@@ -355,52 +355,3 @@ end
texio.reporter = texioreporter
---[[doc--
-
- Adobe Glyph List.
- -------------------------------------------------------------------
-
- Context provides a somewhat different font-age.lua from an unclear
- origin. Unfortunately, the file name it reads from is hard-coded
- in font-enc.lua, so we have to replace the entire table.
-
- This shouldn’t cause any complications. Due to its implementation
- the glyph list will be loaded upon loading a OTF or TTF for the
- first time during a TeX run. (If one sticks to TFM/OFM then it is
- never read at all.) For this reason we can install a metatable that
- looks up the file of our choosing and only falls back to the
- Context one in case it cannot be found.
-
---doc]]--
-
-if fonts then --- need to be running TeX
- if next(fonts.encodings.agl) then
- --- unnecessary because the file shouldn’t be loaded at this time
- --- but we’re just making sure
- fonts.encodings.agl = nil
- collectgarbage"collect"
- end
-
-
- fonts.encodings.agl = { }
-
- setmetatable(fonts.encodings.agl, { __index = function (t, k)
- if k == "unicodes" then
- local glyphlist = resolvers.findfile"luaotfload-glyphlist.lua"
- if glyphlist then
- report ("log", 1, "load", "loading the Adobe glyph list")
- else
- glyphlist = resolvers.findfile"font-age.lua"
- report ("both", 0, "load",
- "loading the extended glyph list from ConTeXt")
- end
- local unicodes = dofile(glyphlist)
- fonts.encodings.agl = { unicodes = unicodes }
- return unicodes
- else
- return nil
- end
- end })
-end
-
--- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/src/luaotfload-main.lua b/src/luaotfload-main.lua
index e8f05d6..b633ed7 100644
--- a/src/luaotfload-main.lua
+++ b/src/luaotfload-main.lua
@@ -1,6 +1,6 @@
-----------------------------------------------------------------------
-- FILE: luaotfload-main.lua
--- DESCRIPTION: Luaotfload initialization
+-- DESCRIPTION: Luaotfload entry point
-- REQUIREMENTS: luatex v.0.80 or later; packages lualibs, luatexbase
-- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang
-- VERSION: same as Luaotfload
@@ -20,9 +20,7 @@ luaotfload.log = luaotfload.log or { }
luaotfload.version = "2.6"
luaotfload.loaders = { }
luaotfload.min_luatex_version = 79 --- i. e. 0.79
-luaotfload.fontloader_package = "fontloader" --- default: from current Context
-----------.fontloader_package = "slim"
-
+luaotfload.fontloader_package = "reference" --- default: from current Context
local authors = "\z
Hans Hagen,\z
@@ -67,16 +65,8 @@ luaotfload.module = {
--doc]]--
local luatexbase = luatexbase
-
local require = require
-local setmetatable = setmetatable
-local type, next = type, next
-local stringlower = string.lower
-local stringformat = string.format
-
-local kpsefind_file = kpse.find_file
-local lfsisfile = lfs.isfile
-
+local type = type
local add_to_callback = luatexbase.add_to_callback
local create_callback = luatexbase.create_callback
local reset_callback = luatexbase.reset_callback
@@ -155,13 +145,11 @@ luaotfload.loaders.luaotfload = load_luaotfload_module
luaotfload.loaders.fontloader = load_fontloader_module
luaotfload.init = load_luaotfload_module "init" --- fontloader initialization
-luaotfload.init.init ()
+local store = luaotfload.init.early ()
local log = luaotfload.log
local logreport = log.report
-load_luaotfload_module "override" --- load glyphlist on demand
-
--[[doc--
Now we load the modules written for \identifier{luaotfload}.
@@ -175,232 +163,18 @@ if not config.actions.apply_defaults () then
logreport ("log", 0, "load", "Configuration unsuccessful.")
end
+luaotfload.init.main (store)
+
load_luaotfload_module "loaders" --- Type1 font wrappers
load_luaotfload_module "database" --- Font management.
load_luaotfload_module "colors" --- Per-font colors.
-if not config.actions.reconfigure () then
- logreport ("log", 0, "load", "Post-configuration hooks failed.")
-end
-
---[[doc--
-
- Relying on the \verb|name:| resolver for everything has been the
- source of permanent trouble with the database.
- With the introduction of the new syntax parser we now have enough
- granularity to distinguish between the \XETEX emulation layer and
- the genuine \verb|name:| and \verb|file:| lookups of \LUATEX-Fonts.
- Another benefit is that we can now easily plug in or replace new
- lookup behaviors if necessary.
- The name resolver remains untouched, but it calls
- \luafunction{fonts.names.resolve()} internally anyways (see
- \fileent{luaotfload-database.lua}).
-
---doc]]--
-
-local filesuffix = file.suffix
-local fileremovesuffix = file.removesuffix
-local request_resolvers = fonts.definers.resolvers
-local formats = fonts.formats
-local names = fonts.names
-formats.ofm = "type1"
-
-fonts.encodings.known = fonts.encodings.known or { }
-
---[[doc--
-
- \identifier{luaotfload} promises easy access to system fonts.
- Without additional precautions, this cannot be achieved by
- \identifier{kpathsea} alone, because it searches only the
- \fileent{texmf} directories by default.
- Although it is possible for \identifier{kpathsea} to include extra
- paths by adding them to the \verb|OSFONTDIR| environment variable,
- this is still short of the goal »\emphasis{it just works!}«.
- When building the font database \identifier{luaotfload} scans
- system font directories anyways, so we already have all the
- information for looking sytem fonts.
- With the release version 2.2 the file names are indexed in the
- database as well and we are ready to resolve \verb|file:| lookups
- this way.
- Thus we no longer need to call the \identifier{kpathsea} library in
- most cases when looking up font files, only when generating the
- database, and when verifying the existence of a file in the
- \fileent{texmf} tree.
-
---doc]]--
-
-local resolve_file = names.font_file_lookup
-
-local file_resolver = function (specification)
- local name = resolve_file (specification.name)
- local suffix = filesuffix(name)
- if formats[suffix] then
- specification.forced = stringlower (suffix)
- specification.forcedname = file.removesuffix(name)
- else
- specification.name = name
- end
-end
-
-request_resolvers.file = file_resolver
-
---[[doc--
-
- We classify as \verb|anon:| those requests that have neither a
- prefix nor brackets. According to Khaled\footnote{%
- \url{https://github.com/phi-gamma/luaotfload/issues/4#issuecomment-17090553}.
- }
- they are the \XETEX equivalent of a \verb|name:| request, so we
- will be treating them as such.
-
---doc]]--
-
---request_resolvers.anon = request_resolvers.name
-
---[[doc--
-
- There is one drawback, though.
- This syntax is also used for requesting fonts in \identifier{Type1}
- (\abbrev{tfm}, \abbrev{ofm}) format.
- These are essentially \verb|file:| lookups and must be caught
- before the \verb|name:| resolver kicks in, lest they cause the
- database to update.
- Even if we were to require the \verb|file:| prefix for all
- \identifier{Type1} requests, tests have shown that certain fonts
- still include further fonts (e.~g. \fileent{omlgcb.ofm} will ask
- for \fileent{omsecob.tfm}) \emphasis{using the old syntax}.
- For this reason, we introduce an extra check with an early return.
-
---doc]]--
-
-local type1_formats = { "tfm", "ofm", "TFM", "OFM", }
-
-request_resolvers.anon = function (specification)
- local name = specification.name
- for i=1, #type1_formats do
- local format = type1_formats[i]
- local suffix = filesuffix (name)
- if resolvers.findfile(name, format) then
- local usename = suffix == format and file.removesuffix (name) or name
- specification.forcedname = file.addsuffix (usename, format)
- specification.forced = format
- return
- end
- end
- --- under some weird circumstances absolute paths get
- --- passed to the definer; we have to catch them
- --- before the name: resolver misinterprets them.
- name = specification.specification
- local exists, _ = lfsisfile(name)
- if exists then --- garbage; we do this because we are nice,
- --- not because it is correct
- logreport ("log", 1, "load", "file %q exists", name)
- logreport ("log", 1, "load",
- "... overriding borked anon: lookup with path: lookup")
- specification.name = name
- request_resolvers.path(specification)
- return
- end
- request_resolvers.name(specification)
-end
-
---[[doc--
-
- Prior to version 2.2, \identifier{luaotfload} did not distinguish
- \verb|file:| and \verb|path:| lookups, causing complications with
- the resolver.
- Now we test if the requested name is an absolute path in the file
- system, otherwise we fall back to the \verb|file:| lookup.
-
---doc]]--
-
-request_resolvers.path = function (specification)
- local name = specification.name
- local exists, _ = lfsisfile(name)
- if not exists then -- resort to file: lookup
- logreport ("log", 0, "load",
- "path lookup of %q unsuccessful, falling back to file:",
- name)
- file_resolver (specification)
- else
- local suffix = filesuffix (name)
- if formats[suffix] then
- specification.forced = stringlower (suffix)
- specification.name = file.removesuffix(name)
- specification.forcedname = name
- else
- specification.name = name
- end
- end
-end
-
---[[doc--
-
- {\bfseries EXPERIMENTAL}:
- \identifier{kpse}-only resolver, for those who can do without
- system fonts.
-
---doc]]--
-
-request_resolvers.kpse = function (specification)
- local name = specification.name
- local suffix = filesuffix(name)
- if suffix and formats[suffix] then
- name = file.removesuffix(name)
- if resolvers.findfile(name, suffix) then
- specification.forced = stringlower (suffix)
- specification.forcedname = name
- return
- end
- end
- for t, format in next, formats do --- brute force
- if kpse.find_file (name, format) then
- specification.forced = t
- specification.name = name
- return
- end
- end
-end
-
---[[doc--
-
- The \verb|name:| resolver.
-
---doc]]--
-
---- fonts.names.resolvers.name -- Customized version of the
---- generic name resolver.
+luaotfload.resolvers = load_luaotfload_module "resolvers" --- Font lookup
-request_resolvers.name = function (specification)
- local resolver = names.resolve_cached
- if config.luaotfload.run.resolver == "normal" then
- resolver = names.resolve_name
- end
- local resolved, subfont = resolver (specification)
- if resolved then
- logreport ("log", 0, "load", "Lookup/name: %q -> \"%s%s\"",
- specification.name,
- resolved,
- subfont and stringformat ("(%d)", subfont) or "")
- specification.resolved = resolved
- specification.sub = subfont
- specification.forced = stringlower (filesuffix (resolved) or "")
- specification.forcedname = resolved
- specification.name = fileremovesuffix (resolved)
- else
- file_resolver (specification)
- end
-end
-
---[[doc--
+luaotfload.resolvers.install ()
- Also {\bfseries EXPERIMENTAL}: custom file resolvers via callback.
-
---doc]]--
-create_callback("luaotfload.resolve_font", "simple", dummy_function)
-
-request_resolvers.my = function (specification)
- call_callback("luaotfload.resolve_font", specification)
+if not config.actions.reconfigure () then
+ logreport ("log", 0, "load", "Post-configuration hooks failed.")
end
--[[doc--
diff --git a/src/luaotfload-override.lua b/src/luaotfload-override.lua
deleted file mode 100644
index b75530b..0000000
--- a/src/luaotfload-override.lua
+++ /dev/null
@@ -1,52 +0,0 @@
-if not modules then modules = { } end modules ["luaotfload-override"] = {
- version = "2.5",
- comment = "companion to Luaotfload",
- author = "Khaled Hosny, Elie Roux, Philipp Gesang",
- copyright = "Luaotfload Development Team",
- license = "GNU GPL v2.0"
-}
-
-local findfile = resolvers.findfile
-local encodings = fonts.encodings
-
-local log = luaotfload.log
-local report = log.report
-
---[[doc--
-
- Adobe Glyph List.
- -------------------------------------------------------------------
-
- Context provides a somewhat different font-age.lua from an unclear
- origin. Unfortunately, the file name it reads from is hard-coded
- in font-enc.lua, so we have to replace the entire table.
-
- This shouldn’t cause any complications. Due to its implementation
- the glyph list will be loaded upon loading a OTF or TTF for the
- first time during a TeX run. (If one sticks to TFM/OFM then it is
- never read at all.) For this reason we can install a metatable that
- looks up the file of our choosing and only falls back to the
- Context one in case it cannot be found.
-
---doc]]--
-
-encodings.agl = { }
-
-setmetatable(fonts.encodings.agl, { __index = function (t, k)
- if k ~= "unicodes" then
- return nil
- end
- local glyphlist = findfile "luaotfload-glyphlist.lua"
- if glyphlist then
- report ("log", 1, "load", "loading the Adobe glyph list")
- else
- glyphlist = findfile "font-age.lua"
- report ("both", 0, "load",
- "loading the extended glyph list from ConTeXt")
- end
- local unicodes = dofile(glyphlist)
- encodings.agl = { unicodes = unicodes }
- return unicodes
-end })
-
--- vim:tw=71:sw=4:ts=4:expandtab
diff --git a/src/luaotfload-resolvers.lua b/src/luaotfload-resolvers.lua
new file mode 100644
index 0000000..42ea2fd
--- /dev/null
+++ b/src/luaotfload-resolvers.lua
@@ -0,0 +1,256 @@
+#!/usr/bin/env texlua
+-----------------------------------------------------------------------
+-- FILE: luaotfload-resolvers.lua
+-- USAGE: ./luaotfload-resolvers.lua
+-- DESCRIPTION: Resolvers for hooking into the fontloader
+-- REQUIREMENTS: Luaotfload and a decent bit of courage
+-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>
+-- VERSION: 1.0
+-- CREATED: 2015-07-23 07:31:50+0200
+-----------------------------------------------------------------------
+--
+--- The bare fontloader uses a set of simplistic file name resolvers
+--- that must be overloaded by the user (i. e. us).
+
+if not lualibs then error "this module requires Luaotfload" end
+if not luaotfload then error "this module requires Luaotfload" end
+
+--[[doc--
+
+ Relying on the \verb|name:| resolver for everything has been the
+ source of permanent trouble with the database.
+ With the introduction of the new syntax parser we now have enough
+ granularity to distinguish between the \XETEX emulation layer and
+ the genuine \verb|name:| and \verb|file:| lookups of \LUATEX-Fonts.
+ Another benefit is that we can now easily plug in or replace new
+ lookup behaviors if necessary.
+ The name resolver remains untouched, but it calls
+ \luafunction{fonts.names.resolve()} internally anyways (see
+ \fileent{luaotfload-database.lua}).
+
+--doc]]--
+
+local next = next
+local kpsefind_file = kpse.find_file
+local lfsisfile = lfs.isfile
+local stringlower = string.lower
+local stringformat = string.format
+local filesuffix = file.suffix
+local fileremovesuffix = file.removesuffix
+local formats = fonts.formats
+local names = fonts.names
+local encodings = fonts.encodings
+local luatexbase = luatexbase
+local logreport = luaotfload.log.report
+
+formats.ofm = "type1"
+encodings.known = encodings.known or { }
+
+--[[doc--
+
+ \identifier{luaotfload} promises easy access to system fonts.
+ Without additional precautions, this cannot be achieved by
+ \identifier{kpathsea} alone, because it searches only the
+ \fileent{texmf} directories by default.
+ Although it is possible for \identifier{kpathsea} to include extra
+ paths by adding them to the \verb|OSFONTDIR| environment variable,
+ this is still short of the goal »\emphasis{it just works!}«.
+ When building the font database \identifier{luaotfload} scans
+ system font directories anyways, so we already have all the
+ information for looking sytem fonts.
+ With the release version 2.2 the file names are indexed in the
+ database as well and we are ready to resolve \verb|file:| lookups
+ this way.
+ Thus we no longer need to call the \identifier{kpathsea} library in
+ most cases when looking up font files, only when generating the
+ database, and when verifying the existence of a file in the
+ \fileent{texmf} tree.
+
+--doc]]--
+
+local resolve_file
+resolve_file = function (specification)
+ local name = names.lookup_font_file (specification.name)
+ local suffix = filesuffix (name)
+ if formats[suffix] then
+ specification.forced = stringlower (suffix)
+ specification.forcedname = fileremovesuffix(name)
+ else
+ specification.name = name
+ end
+end
+
+--[[doc--
+
+ Prior to version 2.2, \identifier{luaotfload} did not distinguish
+ \verb|file:| and \verb|path:| lookups, causing complications with
+ the resolver.
+ Now we test if the requested name is an absolute path in the file
+ system, otherwise we fall back to the \verb|file:| lookup.
+
+--doc]]--
+
+local resolve_path
+resolve_path = function (specification)
+ local name = specification.name
+ local exists, _ = lfsisfile(name)
+ if not exists then -- resort to file: lookup
+ logreport ("log", 0, "load",
+ "path lookup of %q unsuccessful, falling back to file:",
+ name)
+ resolve_file (specification)
+ else
+ local suffix = filesuffix (name)
+ if formats[suffix] then
+ specification.forced = stringlower (suffix)
+ specification.name = fileremovesuffix(name)
+ specification.forcedname = name
+ else
+ specification.name = name
+ end
+ end
+end
+
+--[[doc--
+
+ The \verb|name:| resolver.
+
+--doc]]--
+
+--- fonts.names.resolvers.name -- Customized version of the
+--- generic name resolver.
+
+local resolve_name
+resolve_name = function (specification)
+ local resolver = names.lookup_font_name_cached
+ if config.luaotfload.run.resolver == "normal" then
+ resolver = names.lookup_font_name
+ end
+ local resolved, subfont = resolver (specification)
+ if resolved then
+ logreport ("log", 0, "load", "Lookup/name: %q -> \"%s%s\"",
+ specification.name,
+ resolved,
+ subfont and stringformat ("(%d)", subfont) or "")
+ specification.resolved = resolved
+ specification.sub = subfont
+ specification.forced = stringlower (filesuffix (resolved) or "")
+ specification.forcedname = resolved
+ specification.name = fileremovesuffix (resolved)
+ else
+ resolve_file (specification)
+ end
+end
+
+--[[doc--
+
+ We classify as \verb|anon:| those requests that have neither a
+ prefix nor brackets. According to Khaled\footnote{%
+ % XXX dead link‽
+ \url{https://github.com/phi-gamma/luaotfload/issues/4#issuecomment-17090553}.
+ }
+ they are the \XETEX equivalent of a \verb|name:| request, so we
+ will be treating them as such or, at least, in a similar fashion.
+
+ Not distinguishing between “anon” and “name” requests has a serious
+ drawback: The syntax is overloaded for requesting fonts in
+ \identifier{Type1} (\abbrev{tfm}, \abbrev{ofm}) format.
+ These are essentially \verb|file:| lookups and must be caught
+ before the \verb|name:| resolver kicks in, lest they cause the
+ database to update.
+ Even if we were to require the \verb|file:| prefix for all
+ \identifier{Type1} requests, tests have shown that certain fonts
+ still include further fonts (e.~g. \fileent{omlgcb.ofm} will ask
+ for \fileent{omsecob.tfm}) \emphasis{using the old syntax}.
+ For this reason, we introduce an extra check with an early return.
+
+--doc]]--
+
+local type1_formats = { "tfm", "ofm", "TFM", "OFM", }
+
+local resolve_anon
+resolve_anon = function (specification)
+ local name = specification.name
+ for i=1, #type1_formats do
+ local format = type1_formats[i]
+ local suffix = filesuffix (name)
+ if resolvers.findfile(name, format) then
+ local usename = suffix == format and fileremovesuffix (name) or name
+ specification.forcedname = file.addsuffix (usename, format)
+ specification.forced = format
+ return
+ end
+ end
+ --- under some weird circumstances absolute paths get
+ --- passed to the definer; we have to catch them
+ --- before the name: resolver misinterprets them.
+ name = specification.specification
+ local exists, _ = lfsisfile(name)
+ if exists then --- garbage; we do this because we are nice,
+ --- not because it is correct
+ logreport ("log", 1, "load", "file %q exists", name)
+ logreport ("log", 1, "load",
+ "... overriding borked anon: lookup with path: lookup")
+ specification.name = name
+ resolve_path (specification)
+ return
+ end
+ resolve_name (specification)
+end
+
+--[[doc--
+
+ {\bfseries EXPERIMENTAL}:
+ \identifier{kpse}-only resolver, for those who can do without
+ system fonts.
+
+--doc]]--
+
+local resolve_kpse
+resolve_kpse = function (specification)
+ local name = specification.name
+ local suffix = filesuffix (name)
+ if suffix and formats[suffix] then
+ name = fileremovesuffix (name)
+ if resolvers.findfile (name, suffix) then
+ specification.forced = stringlower (suffix)
+ specification.forcedname = name
+ return
+ end
+ end
+ for t, format in next, formats do --- brute force
+ if kpsefind_file (name, format) then
+ specification.forced = t
+ specification.name = name
+ return
+ end
+ end
+end
+
+--[[doc--
+
+ Also {\bfseries EXPERIMENTAL}: custom file resolvers via callback.
+
+--doc]]--
+
+local resolve_my = function (specification)
+ luatexbase.call_callback ("luaotfload.resolve_font", specification)
+end
+
+return {
+ install = function ( )
+ luatexbase.create_callback ("luaotfload.resolve_font", "simple", function () end)
+ logreport ("log", 5, "resolvers", "installing font resolvers", name)
+ local request_resolvers = fonts.definers.resolvers
+ request_resolvers.file = resolve_file
+ request_resolvers.name = resolve_name
+ request_resolvers.anon = resolve_anon
+ request_resolvers.path = resolve_path
+ request_resolvers.kpse = resolve_kpse
+ request_resolvers.my = resolve_my
+ return true
+ end, --- [.install]
+}
+
+--- vim:ft=lua:ts=8:sw=4:et
+