diff options
| -rw-r--r-- | luaotfload.dtx | 454 | 
1 files changed, 228 insertions, 226 deletions
diff --git a/luaotfload.dtx b/luaotfload.dtx index 0025e2f..3998859 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -990,8 +990,12 @@ and the derived files  %<*lua>  % \fi  %    \begin{macrocode} -luaotfload = luaotfload or {} -local luaotfload  = luaotfload +luaotfload                  = luaotfload or {} +local luaotfload            = luaotfload + +config                      = config or { } +config.luaotfload           = config.luaotfload or { } +luaotfload.prefer_merge     = config.luaotfload.prefer_merge or true  luaotfload.module = {      name          = "luaotfload", @@ -1006,6 +1010,7 @@ luaotfload.module = {  local luatexbase = luatexbase  local type, next       = type, next +local setmetatable     = setmetatable  local stringfind       = string.find  local stringsub        = string.sub  local stringmatch      = string.match @@ -1020,13 +1025,11 @@ local reset_callback, call_callback =  local dummy_function = function () end  %    \end{macrocode} -% -% -%    No final decision has been made on how to handle font definition.  At -%    the moment, there are three candidates: The \identifier{generic} -%    callback as hard-coded in the font loader, the \identifier{old} -%    wrapper, and a simplified version of the latter (\identifier{patch}) -%    that does nothing besides applying font patches. +% No final decision has been made on how to handle font definition.  At +% the moment, there are three candidates: The \identifier{generic} +% callback as hard-coded in the font loader, the \identifier{old} +% wrapper, and a simplified version of the latter (\identifier{patch}) +% that does nothing besides applying font patches.  %  %    \begin{macrocode} @@ -1036,26 +1039,22 @@ local error, warning, info, log =      luatexbase.provides_module(luaotfload.module)  %    \end{macrocode} -% -% -%    This is a necessary initalization in order not to rebuild an existing -%    font. -%    Maybe 600 should be replaced by \texmacro{pdfpkresolution} %% (why?) -%    or \luafunction{texconfig.pk_dpi} (and it should be replaced -%    dynamically), but we don't have access (yet) to the -%    \identifier{texconfig} table, so we let it be 600. -%    Anyway, it does still work fine even if \texmacro{pdfpkresolution} is -%    changed. +% This is a necessary initalization in order not to rebuild an existing +% font. +% Maybe 600 should be replaced by \texmacro{pdfpkresolution} %% (why?) +% or \luafunction{texconfig.pk_dpi} (and it should be replaced +% dynamically), but we don't have access (yet) to the +% \identifier{texconfig} table, so we let it be 600. +% Anyway, it does still work fine even if \texmacro{pdfpkresolution} is +% changed.  %  %    \begin{macrocode}  kpse.init_prog("", 600, "/")  %    \end{macrocode} -% -% -%    We set the minimum version requirement for \LUATEX to v0.74, as it was -%    the first version to include version 5.2 of the \LUA interpreter. +% We set the minimum version requirement for \LUATEX to v0.74, as it was +% the first version to include version 5.2 of the \LUA interpreter.  %  %    \begin{macrocode} @@ -1068,13 +1067,10 @@ if tex.luatexversion < luatex_version then  end  %    \end{macrocode} -% -% -%    \subsection{Module loading} -% -%    We load the files imported from \CONTEXT with this function. -%    It automatically prepends the prefix \fileent{luaotfload-} to its -%    argument, so we can refer to the files with their actual \CONTEXT name. +% \subsection{Module loading} +% We load the files imported from \CONTEXT with this function. +% It automatically prepends the prefix \fileent{luaotfload-} to its +% argument, so we can refer to the files with their actual \CONTEXT name.  %  %    \begin{macrocode} @@ -1084,13 +1080,12 @@ local loadmodule = function (name)  end  %    \end{macrocode} -% -%    Before \TeX Live 2013 version, \LUATEX had a bug that made ofm fonts fail -%    when called with their extension. There was a side-effect making ofm -%    totally unloadable when luaotfload was present. The following lines are -%    a patch for this bug. The utility of these lines is questionable as they -%    are not necessary since \TeX Live 2013. They should be removed in the next -%    version. +% Before \TeX Live 2013 version, \LUATEX had a bug that made ofm fonts fail +% when called with their extension. There was a side-effect making ofm +% totally unloadable when luaotfload was present. The following lines are +% a patch for this bug. The utility of these lines is questionable as they +% are not necessary since \TeX Live 2013. They should be removed in the next +% version.  %  %    \begin{macrocode}  local Cs, P, lpegmatch = lpeg.Cs, lpeg.P, lpeg.match @@ -1112,198 +1107,223 @@ local find_vf_file = function (name)  end  %    \end{macrocode} -% -% -% -%    \subsection{Preparing the Font Loader} -%    We treat the fontloader as a black box so behavior is consistent -%    between formats. -%    The wrapper file is \fileent{luaotfload-fonts.lua} which we imported from -%    \href{http://standalone.contextgarden.net/current/context/experimental/tex/generic/context/luatex/}{\LUATEX-Plain}. -%    It has roughly two purposes: -% -%    \begin{enumerate} -% -%       \item insert the functionality required for fontloader; and -% -%       \item put it in place via the respective callbacks. -% -%    \end{enumerate} -% -%    How the first step is executed depends on the presence on the -%    \emphasis{merged font loader code}. -%    In \identifier{luaotfload} this is contained in the file -%    \fileent{luaotfload-fonts-merged.lua}. -%    If this file cannot be found,  the original libraries from \CONTEXT of -%    which the merged code was composed are loaded instead. -% -%    Hans provides two global tables to control the font loader: -% -%      \begin{itemize} -%        \item  \luafunction{generic_context}: -%               encapsulation mechanism, callback functions -%        \item  \luafunction{non generic_context}: -%               customized code insertion -%      \end{itemize} -% -%    With \luafunction{non_generic_context} we can tailor the font loader -%    insertion to our file naming habits (key \luafunction{load_before}). -%    Additionally, \luafunction{skip_loading} can be unset to force loading -%    of the original libraries as though the merged code was absent. -%    Another key, \luafunction{load_after} is called at the time when the -%    font loader is actually inserted. -%    In combination with the option \luafunction{no_callbacks_yet} in -%    \luafunction{generic_context}, we can insert our own, -%    \identifier{luatexbase}-style callback handling here. +% \subsection{Preparing the Font Loader} +% We treat the fontloader as a black box so behavior is consistent +% between formats. +% We do no longer run the intermediate wrapper file +% \fileent{luaotfload-fonts.lua} which we used to import from +% \href{http://standalone.contextgarden.net/current/context/experimental/tex/generic/context/luatex/}{\LUATEX-Plain}. +% Rather, we load the fontloader code directly in the same fashion as +% \identifier{luatex-fonts}. +% How this is executed depends on the presence on the \emphasis{merged +% font loader code}. +% In \identifier{luaotfload} this is contained in the file +% \fileent{luaotfload-merged.lua}. +% If this file cannot be found, the original libraries from \CONTEXT of +% which the merged code was composed are loaded instead. +% +% The imported font loader will call \luafunction{callback.register} once +% while reading \fileent{font-def.lua}. +% This is unavoidable unless we modify the imported files, but harmless +% if we make it call a dummy instead. +% However, this problem might vanish if we decide to do the merging +% ourselves, like the \identifier{lualibs} package does. +% With this step we would obtain the freedom to load our own overrides in +% the process right where they are needed, at the cost of losing +% encapsulation. +% The decision on how to progress is currently on indefinite hold.  %  %    \begin{macrocode} +local starttime = os.gettimeofday() ---- these are obsolescent due to our plan of removing luaotfload-fonts.lua -generic_context      = generic_context or { } -non_generic_context  = non_generic_context or { } +local trapped_register  = callback.register +callback.register       = dummy_function -generic_context.no_callbacks_yet = true +%    \end{macrocode} +% By default, the fontloader requires a number of \emphasis{private +% attributes} for internal use. +% These must be kept consistent with the attribute handling methods as +% provided by \identifier{luatexbase}. +% Our strategy is to override the function that allocates new attributes +% before we initialize the font loader, making it a wrapper around +% \luafunction{luatexbase.new_attribute}.\footnote{% +%     Many thanks, again, to Hans Hagen for making this part +%     configurable! +% } +% The attribute identifiers are prefixed “\fileent{luaotfload@}” to +% avoid name clashes. +% +%    \begin{macrocode} -non_generic_context.luatex_fonts = { -        --- TODO we’ll kill luaotfload-fonts.lua soon, so -        ---      this is gonna vanish, and the file will become -        ---      luaotfload-merged.lua -        load_before     = "luaotfload-fonts-merged.lua", -        skip_loading    = true, -} +do +    local new_attribute    = luatexbase.new_attribute +    local the_attributes   = luatexbase.attributes + +    attributes = attributes or { } + +    attributes.private = function (name) +        local attr   = "luaotfload@" .. name --- used to be: “otfl@” +        local number = the_attributes[attr] +        if not number then +            number = new_attribute(attr) +        end +        return number +    end +end  %    \end{macrocode} -% -% -%    In its raw form, the font loader will write to the terminal quite -%    liberally, not using the proper channels (loggers) even of \CONTEXT. -%    To make it behave we temporarily replace two functions from the -%    \luafunction{texio} library with wrappers that redirect output to the -%    log. -%    Just in case Hans decides to call \luafunction{texio.write*} with the -%    optional target parameter (which he doesn’t at the moment), we catch the -%    first argument and skip it where appropriate. -%    The originals are backed up and restored after loading -%    \fileent{luaotfload-fonts.lua}. -% -%    Should we decide to do our own packaging (we’re capable of that -%    anyways), this will most likely become unnecessary. +% These next lines replicate the behavior of \fileent{luatex-fonts.lua}.  %  %    \begin{macrocode} -local normal_write, normal_write_nl = texio.write, texio.write_nl +local context_environment = { } -local log_template = "luaotfload: %s" -local fake_write = function (first, rest) -    if first == "log" or first == "term" then -- ignore -        normal_write("log", stringformat(log_template, rest)) -    else -        normal_write("log", stringformat(log_template, first)) +local push_namespaces = function () +    log("push namespace for font loader") +    local normalglobal = { } +    for k, v in next, _G do +        normalglobal[k] = v      end +    return normalglobal  end -local fake_write_nl = function (first, rest) -    if first == "log" or first == "term" then -- ignore -        normal_write_nl("log", stringformat(log_template, rest)) + +local pop_namespaces = function (normalglobal, isolate) +    if normalglobal then +        local _G = _G +        local mode = "non-destructive" +        if isolate then mode = "destructive" end +        log("pop namespace from font loader -- "..mode) +        for k, v in next, _G do +            if not normalglobal[k] then +                context_environment[k] = v +                if isolate then +                    _G[k] = nil +                end +            end +        end +        for k, v in next, normalglobal do +            _G[k] = v +        end +        -- just to be sure: +        setmetatable(context_environment,_G)      else -        normal_write_nl("log", stringformat(log_template, first, rest)) +        log("irrecoverable error during pop_namespace: no globals to restore") +        os.exit()      end  end -texio.write, texio.write_nl = fake_write, fake_write_nl -%    \end{macrocode} -% -% -%    The imported font loader will call \luafunction{callback.register} once -%    while reading \fileent{font-def.lua}. -%    This is unavoidable unless we modify the imported files, but harmless -%    if we make it call a dummy instead. -% -%    \begin{macrocode} +luaotfload.context_environment  = context_environment +luaotfload.push_namespaces      = push_namespaces +luaotfload.pop_namespaces       = pop_namespaces -local trapped_register = callback.register -callback.register      = dummy_function +local our_environment = push_namespaces()  %    \end{macrocode} -% -% -%    Now that things are sorted out we can finally load the fontloader. +% The font loader requires that the attribute with index zero be zero. +% We happily oblige. +% (Cf. \fileent{luatex-fonts-nod.lua}.)  %  %    \begin{macrocode} -loadmodule"fonts.lua" +tex.attribute[0] = 0  %    \end{macrocode} -% -% -%    Here we restore the original \luafunction{texio} functions. +% Now that things are sorted out we can finally load the fontloader.  %  %    \begin{macrocode} -texio.write, texio.write_nl = normal_write, normal_write_nl + +loadmodule"merged.lua" + +if fonts then + +    if not fonts._merge_loaded_message_done_ then +        --- a program talking first person -- HH sure believes in strong AI ... +        log[[“I am using the merged version of 'luaotfload.lua' here. If]] +        log[[ you run into problems or experience unexpected behaviour,]] +        log[[ and if you have ConTeXt installed you can try to delete the]] +        log[[ file 'luaotfload-font-merged.lua' as I might then use the]] +        log[[ possibly updated libraries. The merged version is not]] +        log[[ supported as it is a frozen instance. Problems can be]] +        log[[ reported to the ConTeXt mailing list.”]] +    end +    fonts._merge_loaded_message_done_ = true + +else--- the loading sequence is known to change, so this might have to +    --- be updated with future updates! +    --- do not modify it though unless there is a change to the merged +    --- package! +    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") +    loadmodule('luatex-basics-gen.lua') +    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('luatex-fonts-tfm.lua') +    loadmodule('font-oti.lua') +    loadmodule('font-otf.lua') +    loadmodule('font-otb.lua') +    loadmodule('node-inj.lua') +    loadmodule('font-ota.lua') +    loadmodule('font-otn.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') +end --- non-merge fallback scope  %    \end{macrocode} -% -% -%    By default, the fontloader requires a number of \emphasis{private -%    attributes} for internal use. -%    These must be kept consistent with the attribute handling methods as -%    provided by \identifier{luatexbase}. -%    Our strategy is to override the function that allocates new attributes -%    before we initialize the font loader, making it a wrapper around -%    \luafunction{luatexbase.new_attribute}.\footnote{% -%       Many thanks, again, to Hans Hagen for making this part -%       configurable! -%    } -%    The attribute identifiers are prefixed “\fileent{luaotfload@}” to -%    avoid name clashes. +% Here we adjust the globals created during font loader initialization. +% If the second argument to \luafunction{pop_namespaces()} is \verb|true| +% this will restore the state of \luafunction{_G}, eliminating every +% global generated since the last call to \luafunction{push_namespaces()}. +% At the moment we see no reason to do this, and since the font loader is +% considered an essential part of \identifier{luatex} as well as a very +% well organized piece of code, we happily concede it the right to add to +% \luafunction{_G} if needed.  %  %    \begin{macrocode} -do -    local new_attribute    = luatexbase.new_attribute -    local the_attributes   = luatexbase.attributes +pop_namespaces(our_environment, false)-- true) -    attributes = attributes or { } - -    attributes.private = function (name) -        local attr   = "luaotfload@" .. name --- used to be: “otfl@” -        local number = the_attributes[attr] -        if not number then -            number = new_attribute(attr) -        end -        return number -    end -end +log("fontloader loaded in %0.3f seconds", os.gettimeofday()-starttime)  %    \end{macrocode} -% -% -% -%    \subsection{Callbacks} -% -%    After the fontloader is ready we can restore the callback trap from -%    \identifier{luatexbase}. +% \subsection{Callbacks} +% After the fontloader is ready we can restore the callback trap from +% \identifier{luatexbase}.  %  %    \begin{macrocode}  callback.register = trapped_register  %    \end{macrocode} -% -% -%    We do our own callback handling with the means provided by luatexbase. -% -%    Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter} -%    are coupled in \CONTEXT in the concept of \emphasis{node processor}. +% We do our own callback handling with the means provided by luatexbase. +% Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter} +% are coupled in \CONTEXT in the concept of \emphasis{node processor}.  %  %    \begin{macrocode}  add_to_callback("pre_linebreak_filter", -                generic_context.callback_pre_linebreak_filter, +                nodes.simple_font_handler,                  "luaotfload.node_processor",                  1)  add_to_callback("hpack_filter", -                generic_context.callback_hpack_filter, +                nodes.simple_font_handler,                  "luaotfload.node_processor",                  1)  add_to_callback("find_vf_file", @@ -1314,10 +1334,8 @@ loadmodule"lib-dir.lua"    -- required by font-nms  loadmodule"luat-ovr.lua"  %    \end{macrocode} -% -% -%    \CONTEXT does not support ofm, these lines were added in order to make it -%    work. However they do not seem necessary so they are commented for now. +% \CONTEXT does not support ofm, these lines were added in order to make it +% work. However they do not seem necessary so they are commented for now.  %  %    \begin{macrocode}  -- if fonts and fonts.readers.tfm then @@ -1327,10 +1345,7 @@ loadmodule"luat-ovr.lua"  --  --- fonts.readers.sequence[#fonts.readers.sequence+1] = "ofm"  --end  %    \end{macrocode} -% -% -% -%    Now we load the modules written for \identifier{luaotfload}. +% Now we load the modules written for \identifier{luaotfload}.  %  %    \begin{macrocode}  loadmodule"font-pfb.lua"    --- new in 2.0, added 2011 @@ -1339,12 +1354,10 @@ loadmodule"font-clr.lua"  loadmodule"font-ltx.lua"    --- new in 2.0, added 2011  %    \end{macrocode} -% -% -%    This hack makes fonts called with file method found by fonts.names.resolve -%    instead of just trying to find them with kpse. It is necessary in case -%    of fonts that are not accessible by kpse but present in the database, a -%    quite common case under Linux. +% This hack makes fonts called with file method found by fonts.names.resolve +% instead of just trying to find them with kpse. It is necessary in case +% of fonts that are not accessible by kpse but present in the database, a +% quite common case under Linux.  %  %    \begin{macrocode} @@ -1353,33 +1366,27 @@ fonts.definers.resolvers.file = function (specification)  end  %    \end{macrocode} -% -% -%    We create a callback for patching fonts on the fly, to be used by other -%    packages. -%    It initially contains the empty function that we are going to override -%    below. +% We create a callback for patching fonts on the fly, to be used by other +% packages. +% It initially contains the empty function that we are going to override +% below.  %  %    \begin{macrocode}  create_callback("luaotfload.patch_font", "simple", dummy_function)  %    \end{macrocode} -% -% -% -%    This is a wrapper for the imported font loader. -%    As of 2013, everything it does appear to be redundand, so we won’t use -%    it unless somebody points out a cogent reason. -%    Nevertheless, it has been adapted to work with the current structure of -%    font data objects and will stay here for reference / until breakage is -%    reported. -% -%    \emphasis{TODO} -%    This one also enables patching fonts. -%    The current fontloader apparently comes with a dedicated mechanism for -%    that already: enhancers. -%    How those work remains to be figured out. +% This is a wrapper for the imported font loader. +% As of 2013, everything it does appear to be redundand, so we won’t use +% it unless somebody points out a cogent reason. +% Nevertheless, it has been adapted to work with the current structure of +% font data objects and will stay here for reference / until breakage is +% reported. +% \emphasis{TODO} +% This one also enables patching fonts. +% The current fontloader apparently comes with a dedicated mechanism for +% that already: enhancers. +% How those work remains to be figured out.  %  %    \begin{macrocode}  local define_font_wrapper = function (...) @@ -1417,13 +1424,9 @@ local define_font_wrapper = function (...)  end  %    \end{macrocode} -% -% -% -%    \subsection{\CONTEXT override} -% -%    We provide a simplified version of the original font definition -%    callback. +% \subsection{\CONTEXT override} +% We provide a simplified version of the original font definition +% callback.  %  %    \begin{macrocode} @@ -1442,9 +1445,7 @@ caches.compilemethod = "both"  reset_callback("define_font")  %    \end{macrocode} -% -% -%    Finally we register the callbacks +% Finally we register the callbacks.  %  %    \begin{macrocode} @@ -1455,7 +1456,7 @@ if luaotfload.font_definer == "old"  then                    1)  elseif luaotfload.font_definer == "generic"  then    add_to_callback("define_font", -                  generic_context.callback_define_font, +                  fonts.definers.read,                    "luaotfload.define_font",                    1)  elseif luaotfload.font_definer == "patch"  then @@ -1501,6 +1502,7 @@ loadmodule"features.lua"  -- vim:tw=71:sw=4:ts=4:expandtab +  %    \end{macrocode}  %  % \iffalse  | 
