diff options
-rw-r--r-- | luaotfload.dtx | 235 | ||||
-rw-r--r-- | luaotfload.lua | 71 | ||||
-rw-r--r-- | otfl-font-nms.lua | 34 |
3 files changed, 195 insertions, 145 deletions
diff --git a/luaotfload.dtx b/luaotfload.dtx index 9954a32..2446644 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -526,9 +526,6 @@ and the derived files % \iffalse %<*lua> % \fi -% -% \section{Initializations} -% % \begin{macrocode} module("luaotfload", package.seeall) @@ -553,30 +550,63 @@ local add_to_callback, create_callback = local reset_callback, call_callback = luatexbase.reset_callback, luatexbase.call_callback -local dummy_function = function () end +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} luaotfload.font_definer = "patch" --- | “generic” | “old” -local fl_prefix = "otfl" -- “luatex” for luatex-plain +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. +% +% \begin{macrocode} + +kpse.init_prog("", 600, "/") -local error, warning, info, log = luatexbase.provides_module(luaotfload.module) +% \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. +% +% \begin{macrocode} -local luatex_version = 75 +local luatex_version = 74 if tex.luatexversion < luatex_version then warning("LuaTeX v%.2f is old, v%.2f is recommended.", tex.luatexversion/100, luatex_version /100) end + +% \end{macrocode} +% +% \subsection{Module loading} +% +% We load the files imported from \CONTEXT with this function. +% It automatically prepends the prefix \fileent{otfl-} to its argument, +% so we can refer to the files with their actual \CONTEXT name. +% +% \begin{macrocode} + +local fl_prefix = "otfl" -- “luatex” for luatex-plain local loadmodule = function (name) local tofind = fl_prefix .."-"..name local found = find_file(tofind,"tex") @@ -584,7 +614,6 @@ local loadmodule = function (name) log("loading file %s.", found) dofile(found) else - --error("file %s not found.", tofind) error("file %s not found.", tofind) end end @@ -592,8 +621,8 @@ end % \end{macrocode} % % Virtual fonts are resolved via a callback. -% \verb|find_vf_file| derives the name of the virtual font file from the -% filename. +% \luafunction{find_vf_file} derives the name of the virtual font file +% from the filename. % (NB: \CONTEXT handles this likewise in \fileent{font-vf.lua}.) % % \begin{macrocode} @@ -655,10 +684,12 @@ 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 |otfl-fonts.lua| which we imported from -% \LUATEX-Plain. +% The wrapper file is \fileent{otfl-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} @@ -670,32 +701,29 @@ end % \end{enumerate} % % How the first step is executed depends on the presence on the -% \emphasis{merged font loader code}. +% \emph{merged font loader code}. % In \identifier{luaotfload} this is contained in the file -% |otfl-fonts-merged.lua|. +% \fileent{otfl-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 \verb|non_generic_context| we can tailor the font loader insertion -% to our file naming habits (key \verb|load_before|). -% Additionally, \verb|skip_loading| can be unset to force loading of -% the original libraries as though the merged code was absent. -% Another key, \verb|load_after| is called at the time when the font -% loader is actually inserted. -% In combination with the option \verb|no_callbacks_yet| in -% \verb|generic_context|, we can insert our own, +% \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. % % \begin{macrocode} @@ -715,23 +743,62 @@ _G.non_generic_context = { luatex_fonts = { % \end{macrocode} % -% The imported font loader will call \verb|callback.register| once -% (during \verb|font-def.lua|). -% This is unavoidable but harmless, so we make it call a dummy 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. % % \begin{macrocode} + local trapped_register = callback.register callback.register = dummy_function % \end{macrocode} % -% Now that things are sorted out we can load the fontloader. +% Now that things are sorted out we can finally load the fontloader. % % \begin{macrocode} + loadmodule"fonts.lua" % \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{otfl@}” to +% avoid name clashes. +% +% \begin{macrocode} + +do + local new_attribute = luatexbase.new_attribute + local the_attributes = luatexbase.attributes + + _G.attributes = _G.attributes or { } + + _G.attributes.private = function (name) + local attr = "otfl@" .. name + local number = the_attributes[attr] + if not number then + number = new_attribute(attr) + end + return number + end +end + +% \end{macrocode} +% +% +% \subsection{Callbacks} +% % After the fontloader is ready we can restore the callback trap from % \identifier{luatexbase}. % @@ -743,8 +810,8 @@ callback.register = trapped_register % % We do our own callback handling with the means provided by luatexbase. % -% Note: \verb|pre_linebreak_filter| and \verb|hpack_filter| are coupled -% in \CONTEXT\ in the concept of \emphasis{node processor}. +% Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter} +% are coupled in \CONTEXT in the concept of \emph{node processor}. % % \begin{macrocode} @@ -776,26 +843,44 @@ if fonts and fonts.readers.tfm then fonts.readers.ofm = fonts.readers.tfm fonts.handlers.ofm = fonts.handlers.tfm --- empty anyways fonts.formats.ofm = fonts.formats.tfm --- “type1” + --- fonts.readers.sequence[#fonts.readers.sequence+1] = "ofm" -------------------------------------------------------------------- end -loadmodule"font-pfb.lua" +% \end{macrocode} +% +% +% Now we load the modules written for \identifier{luaotfload}. +% +% \begin{macrocode} +loadmodule"font-pfb.lua" --- new in 2.0, added 2011 loadmodule"font-nms.lua" loadmodule"font-clr.lua" -loadmodule"font-ltx.lua" +loadmodule"font-ltx.lua" --- new in 2.0, added 2011 + +% \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. +% +% \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 appears to be redundand, so we won’t use -% it. +% 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 somebody -% reports breakage. +% font data objects and will stay here for reference / until breakage is +% reported. % -% TODO +% \emphasis{TODO} % This one also enables patching fonts. % The current fontloader apparently comes with a dedicated mechanism for % that already: enhancers. @@ -838,36 +923,36 @@ end % \end{macrocode} % +% +% \subsection{\CONTEXT override} +% % We provide a simplified version of the original font definition % callback. % % \begin{macrocode} + +local read_font_file = fonts.definers.read local patch_defined_font = function (...) - local tfmdata = fonts.definers.read(...) + local tfmdata = read_font_file(...)-- spec -> size -> id -> tmfdata if type(tfmdata) == "table" then call_callback("luaotfload.patch_font", tfmdata) end - --inspect(tfmdata.shared.features) return tfmdata end -fonts.mode = "node" caches.compilemethod = "both" -function attributes.private(name) - local attr = "otfl@" .. name - local number = luatexbase.attributes[attr] - if not number then - number = luatexbase.new_attribute(attr) - end - return number -end - reset_callback("define_font") +% \end{macrocode} +% +% Finally we register the callbacks +% +% \begin{macrocode} + if luaotfload.font_definer == "old" then add_to_callback("define_font", - old_define_font_wrapper, + define_font_wrapper, "luaotfload.define_font", 1) elseif luaotfload.font_definer == "generic" then @@ -884,30 +969,6 @@ end loadmodule"features.lua" ---[==[ ----- is this still necessary? -local set_sscale_diments = function (tfmdata) - local mathconstants = tfmdata.MathConstants - if mathconstants then - local tfmparameters = tfmdata.parameters - if mathconstants.ScriptPercentScaleDown then - tfmparameters[10] = mathconstants.ScriptPercentScaleDown - else -- resort to plain TeX default - tfmparameters[10] = 70 - end - if mathconstants.ScriptScriptPercentScaleDown then - tfmparameters[11] = mathconstants.ScriptScriptPercentScaleDown - else -- resort to plain TeX default - tfmparameters[11] = 50 - end - end -end - -add_to_callback("luaotfload.patch_font", - set_sscale_diments, - "unicodemath.set_sscale_diments") -]==] - -- vim:tw=71:sw=4:ts=4:expandtab % \end{macrocode} diff --git a/luaotfload.lua b/luaotfload.lua index bdbae0e..70d89a2 100644 --- a/luaotfload.lua +++ b/luaotfload.lua @@ -218,67 +218,34 @@ Now that things are sorted out we can finally load the fontloader. loadmodule"fonts.lua" --[[doc-- -By default, the fontloader requires a number of \emph{private +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}. -Previously, when \identifier{luaotfload} imported individual files from -\CONTEXT, the strategy was to override the function that allocates new -attributes at the appropriate time during initialization, making it a -wrapper around \luafunction{luatexbase.new_attribute}. - -\begin{verbatim} -attributes.private = function (name) - local attr = "otfl@" .. name - local number = luatexbase.attributes[attr] - if not number then - number = luatexbase.new_attribute(attr) - end - return number -end -\end{verbatim} - -Now that the fontloader comes as a package, this hack is no longer -applicable. -The attribute handler installed by \identifier{luatex-fonts} (see the -file \fileent{otfl-basics-nod.lua}) cannot be intercepted before the -first call to it takes place. -While it is not feasible to prevent insertion of attributes at the -wrong places, we can still retrieve them from the closure surrounding -the allocation function \luafunction{attributes.private} -using \LUA’s introspection features. - -The recovered attribute identifiers are prefixed “\fileent{otfl@}” to +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{otfl@}” to avoid name clashes. --doc]]-- do - local debug_getupvalue = debug.getupvalue - - local nups = debug.getinfo(attributes.private, "u").nups - local nup, numbers = 0 - while nup <= nups do - nup = nup + 1 - local upname, upvalue = debug_getupvalue(attributes.private, nup) - if upname == "numbers" then - numbers = upvalue - break - end - end - if numbers then - local luatexbase_attributes = luatexbase.attributes - local prefix = "otfl@" - --- re-register attributes from “numbers” - --- ... pull request for luatexbase pending - for name, num in next, numbers do - name = prefix .. name - luatexbase_attributes[name] = num + local new_attribute = luatexbase.new_attribute + local the_attributes = luatexbase.attributes + + _G.attributes = _G.attributes or { } + + _G.attributes.private = function (name) + local attr = "otfl@" .. name + local number = the_attributes[attr] + if not number then + number = new_attribute(attr) end + return number end - --- The definitions used by the fontloader are never - --- called again so it is safe to nil them, I suppose. - debug.setupvalue(attributes.private, nup, { }) - _G.attributes = nil --- needed for initialization only end --[[doc-- diff --git a/otfl-font-nms.lua b/otfl-font-nms.lua index 609d4e1..79e7217 100644 --- a/otfl-font-nms.lua +++ b/otfl-font-nms.lua @@ -189,6 +189,28 @@ font database created by the mkluatexfontdb script. --doc]]-- + +--- +--- the request specification has the fields: +--- +--- · features: table +--- · normal: set of { ccmp clig itlc kern liga locl mark mkmk rlig } +--- · ??? +--- · forced: string +--- · lookup: "name" | "file" +--- · method: string +--- · name: string +--- · resolved: string +--- · size: int +--- · specification: string (== <lookup> ":" <name>) +--- · sub: string +--- +--- the return value of “resolve” is the file name of the requested +--- font + +--- 'a -> 'a -> table -> (string * string | bool * bool) +--- note by phg: I added a third return value that indicates a +--- successful lookup as this cannot be inferred from the other values. resolve = function (_,_,specification) -- the 1st two parameters are used by ConTeXt local name = sanitize_string(specification.name) local style = sanitize_string(specification.style) or "regular" @@ -282,7 +304,7 @@ resolve = function (_,_,specification) -- the 1st two parameters are used by Con "font family='%s', subfamily='%s' found: %s", name, style, found[1].filename[1] ) - return found[1].filename[1], found[1].filename[2] + return found[1].filename[1], found[1].filename[2], true end elseif #found > 1 then -- we found matching font(s) but not in the requested optical @@ -303,10 +325,10 @@ resolve = function (_,_,specification) -- the 1st two parameters are used by Con "font family='%s', subfamily='%s' found: %s", name, style, closest.filename[1] ) - return closest.filename[1], closest.filename[2] + return closest.filename[1], closest.filename[2], true end elseif found.fallback then - return found.fallback.filename[1], found.fallback.filename[2] + return found.fallback.filename[1], found.fallback.filename[2], true end -- no font found so far if not reloaded then @@ -316,10 +338,10 @@ resolve = function (_,_,specification) -- the 1st two parameters are used by Con reloaded = true return resolve(_,_,specification) else - -- else, fallback to filename + -- else, fallback to requested name -- XXX: specification.name is empty with absolute paths, looks -- like a bug in the specification parser - return specification.name, false + return specification.name, false, false end end else @@ -329,7 +351,7 @@ resolve = function (_,_,specification) -- the 1st two parameters are used by Con reloaded = true return resolve(_,_,specification) else - return specification.name, false + return specification.name, false, false end end end |