From f48b1743185bb89337a9c8224ba05628c106128e Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 15 Apr 2013 20:27:36 +0200 Subject: raw import luaotfload.lua into luaotfload.dtx --- luaotfload.dtx | 512 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 310 insertions(+), 202 deletions(-) (limited to 'luaotfload.dtx') diff --git a/luaotfload.dtx b/luaotfload.dtx index 954e40c..7f1cbdd 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -67,7 +67,7 @@ and the derived files \file{luaotfload.sty}{\from{luaotfload.dtx}{package}}% } -% The following hacks are to generate a lua file with lua comments starting by +% The following hacks are to generate a lua file with lua comments starting with % -- instead of %% \def\MetaPrefix{-- } @@ -468,269 +468,377 @@ and the derived files % \iffalse %<*lua> % \fi -% -% \section{Initializations} -% % \begin{macrocode} module("luaotfload", package.seeall) -% \end{macrocode} -% -% \begin{macrocode} + luaotfload.module = { name = "luaotfload", - version = 2.0, - date = "2011/10/06", + version = 2.2, + date = "2013/04/15", description = "OpenType layout system.", author = "Elie Roux & Hans Hagen", copyright = "Elie Roux", license = "CC0" } + +local luatexbase = luatexbase + +local type, next, dofile = type, next, dofile +local stringfind = string.find +local find_file = kpse.find_file + +local add_to_callback, create_callback = + luatexbase.add_to_callback, luatexbase.create_callback +local reset_callback, call_callback = + luatexbase.reset_callback, luatexbase.call_callback + +local dummy_function = function () end + % \end{macrocode} % -% \begin{macrocode} -local error, warning, info, log = luatexbase.provides_module(luaotfload.module) -% \end{macrocode} -% -% The minimal required \luatex version. -% -% \begin{macrocode} -local luatex_version = 70 -% \end{macrocode} +% No final decision has been made on how to handle font definition. +% At the moment, there are three candidates: The \textsf{generic} +% callback as hard-coded in the font loader, the \textsf{old} wrapper, +% and a simplified version of the latter (\textsf{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) + +local luatex_version = 75 + 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} -% -% Some required functions missing from \textsf{lualibs} package. -% -% \begin{macrocode} -function table.reversed(t) - if t then - local tt, tn = { }, #t - if tn > 0 then - local ttn = 0 - for i=tn,1,-1 do - ttn = ttn + 1 - tt[ttn] = t[i] - end - end - return tt +local loadmodule = function (name) + local tofind = fl_prefix .."-"..name + local found = find_file(tofind,"tex") + if found then + log("loading file %s.", found) + dofile(found) + else + --error("file %s not found.", tofind) + error("file %s not found.", tofind) end end + % \end{macrocode} % -% \begin{macrocode} -function table.derive(parent) - local child = { } - if parent then - setmetatable(child,{ __index = parent }) - end - return child -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. +% (NB: \CONTEXT\ handles this likewise in \textsf{font-vf.lua}.) % % \begin{macrocode} -function string.quoted(str) - return string.format("%q",str) +local Cs, P, lpegmatch = lpeg.Cs, lpeg.P, lpeg.match + +local p_dot, p_slash = P".", P"/" +local p_suffix = (p_dot * (1 - p_dot - p_slash)^1 * P(-1)) / "" +local p_removesuffix = Cs((p_suffix + 1)^1) + +local find_vf_file = function (name) + local fullname = find_file(name, "ovf") + if not fullname then + --fullname = find_file(file.removesuffix(name), "ovf") + fullname = find_file(lpegmatch(p_removesuffix, name), "ovf") + end + if fullname then + log("loading virtual font file %s.", fullname) + end + return fullname end + +--[[-- keep --]] +--- from Hans (all merged): + +--- file name modified include name +--- × basics-gen.lua t luat-basics-gen +--- × font-def -> fonts-def t luatex-font-def (there’s also the normal font-def!) +--- × fonts-enc f luatex-font-enc +--- × fonts-ext t luatex-fonts-ext +--- × fonts-lua f luatex-fonts-lua +--- fonts-tfm f luatex-fonts-tfm +--- × fonts-cbk f luatex-fonts-lua + +--- from Hans (unmerged): +--- font-otc.lua -> otfl-font-otc.lua + +--- from luaotfload: +--- otfl-luat-ovr.lua -- override some luat-dum functions +--- otfl-font-clr.lua +--- otfl-font-ltx.lua +--- otfl-font-nms.lua +--- otfl-font-pfb.lua -- ? + +--[[-- new --]] +--- basics-nod (merged as fonts-nod !) +--- fonts-demo-vf-1.lua +--- fonts-syn (merged) + +--[[-- merged, to be dropped --]] +--- otfl-data-con.lua +--- otfl-font-cid.lua +--- otfl-font-con.lua +--- otfl-font-ini.lua +--- otfl-font-ota.lua +--- otfl-font-otb.lua +--- otfl-font-otf.lua +--- otfl-font-oti.lua +--- otfl-font-otn.lua + % \end{macrocode} % -% \section{Module loading} +% 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. +% It has roughly two purposes: +% (\textit{1}) insert the functionality required for fontloader, and +% (\textit{2}) put it in place via the respective callbacks. +% How the first step is executed depends on the presence on the +% \emph{merged font loader code}. +% In \textsf{luaotfload} this is contained in the file +% |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{tabular}{ll} +% \texttt{generic\textunderscore context} & +% encapsulation mechanism, callback functions +% \\ +% \texttt{non\textunderscore generic\textunderscore context} & +% customized code insertion +% \\ +% \end{tabular} +% 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, +% \textsf{luatexbase}-style callback handling here. % % \begin{macrocode} -require('otfl-basics-gen.lua') -require('otfl-luat-ovr.lua') -- overrides some otfl-basics-gen.lua functions -require('otfl-data-con.lua') -require('otfl-basics-nod.lua') +if not _G. generic_context then _G. generic_context = { } end +if not _G.non_generic_context then _G.non_generic_context = { } end + +local generic_context = generic_context +local non_generic_context =non_generic_context + +generic_context.no_callbacks_yet = true + +_G.non_generic_context = { luatex_fonts = { + load_before = "otfl-fonts-merged.lua", + -- load_after = nil, --- TODO, this is meant for callbacks + skip_loading = true, +}} + % \end{macrocode} % -% By default \context takes some private attributes for internal use. To -% avoide attribute clashes with other packages, we override the function -% that allocates new attributes, making it a wraper around -% |luatexbase.new_attribute()|. We also prefix attributes with |otfl@| to -% avoid possiple name clashes. +% 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. % % \begin{macrocode} -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 -% \end{macrocode} -% -% \begin{macrocode} -require('otfl-font-ini.lua') -require('otfl-font-con.lua') -require('otfl-fonts-enc.lua') -require('otfl-font-cid.lua') -require('otfl-font-map.lua') -require('otfl-font-nms.lua') -require('otfl-fonts-tfm.lua') -require('otfl-font-oti.lua') -require('otfl-font-otf.lua') -require('otfl-font-pfb.lua') -require('otfl-font-otb.lua') -require('otfl-node-inj.lua') -require('otfl-font-otn.lua') -require('otfl-font-ota.lua') -require('otfl-font-otc.lua') -require('otfl-fonts-lua.lua') -require('otfl-font-def.lua') -require('otfl-font-ltx.lua') -require('otfl-fonts-ext.lua') -require('otfl-fonts-cbk.lua') -require('otfl-font-clr.lua') +local trapped_register = callback.register +callback.register = dummy_function + % \end{macrocode} % -% Here we override some defaults set in \context code. +% Now that things are sorted out we can load the fontloader. % % \begin{macrocode} -fonts.mode = "node" -caches.compilemethod = "both" +loadmodule"fonts.lua" + % \end{macrocode} % -% Now overriding the \context's definition of |tlig| and |trep| features, -% using code points instead of glyph names to make it font independent. +% After the fontloader is ready we can restore the callback trap from +% \textsf{luatexbase}. % % \begin{macrocode} -local everywhere = { ["*"] = { ["*"] = true } } - -local tlig = { - { - type = "substitution", - features = everywhere, - data = { - [0x0022] = 0x201D, -- quotedblright - [0x0027] = 0x2019, -- quoteleft - [0x0060] = 0x2018, -- quoteright - }, - flags = { }, - }, - { - type = "ligature", - features = everywhere, - data = { - [0x2013] = {0x002D, 0x002D}, -- endash - [0x2014] = {0x002D, 0x002D, 0x002D}, -- emdash - [0x201C] = {0x2018, 0x2018}, -- quotedblleft - [0x201D] = {0x2019, 0x2019}, -- quotedblright - [0x201E] = {0x002C, 0x002C}, -- quotedblbase - [0x00A1] = {0x0021, 0x2018}, -- exclamdown - [0x00BF] = {0x003F, 0x2018}, -- questiondown - }, - flags = { }, - }, - { - type = "ligature", - features = everywhere, - data = { - [0x201C] = {0x0060, 0x0060}, -- quotedblleft - [0x201D] = {0x0027, 0x0027}, -- quotedblright - [0x00A1] = {0x0021, 0x0060}, -- exclamdown - [0x00BF] = {0x003F, 0x0060}, -- questiondown - }, - flags = { }, - }, -} -fonts.handlers.otf.addfeature("tlig", tlig) -fonts.handlers.otf.addfeature("trep", { }) -- empty, all in tlig now +callback.register = trapped_register + % \end{macrocode} % -% And overriding the \context's definition of |anum|. +% 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 \emph{node processor}. % % \begin{macrocode} -local anum_arabic = { - [0x0030] = 0x0660, - [0x0031] = 0x0661, - [0x0032] = 0x0662, - [0x0033] = 0x0663, - [0x0034] = 0x0664, - [0x0035] = 0x0665, - [0x0036] = 0x0666, - [0x0037] = 0x0667, - [0x0038] = 0x0668, - [0x0039] = 0x0669, -} -local anum_persian = { - [0x0030] = 0x06F0, - [0x0031] = 0x06F1, - [0x0032] = 0x06F2, - [0x0033] = 0x06F3, - [0x0034] = 0x06F4, - [0x0035] = 0x06F5, - [0x0036] = 0x06F6, - [0x0037] = 0x06F7, - [0x0038] = 0x06F8, - [0x0039] = 0x06F9, -} +add_to_callback("pre_linebreak_filter", + generic_context.callback_pre_linebreak_filter, + "luaotfload.node_processor", + 1) +add_to_callback("hpack_filter", + generic_context.callback_hpack_filter, + "luaotfload.node_processor", + 1) +add_to_callback("find_vf_file", + find_vf_file, "luaotfload.find_vf_file") -local function valid(data) - local features = data.resources.features - if features then - for k, v in next, features do - for k, v in next, v do - if v.arab then - return true - end - end - end - end +loadmodule"font-otc.lua" -- TODO check what we can drop from otfl-features + +loadmodule"lib-dir.lua" -- required by font-nms +loadmodule"luat-ovr.lua" + +if fonts and fonts.readers.tfm then + -------------------------------------------------------------------- + --- OFM; read this first + -------------------------------------------------------------------- + --- I can’t quite make out whether this is still relevant + --- as those ofm fonts always fail, even in the 2011 version + --- (mktexpk: don't know how to create bitmap font for omarabb.ofm) + --- the font loader appears to read ofm like tfm so if this + --- hack was supposed achieve that, we should excise it anyways + fonts.readers.ofm = fonts.readers.tfm + fonts.handlers.ofm = fonts.handlers.tfm --- empty anyways + fonts.formats.ofm = fonts.formats.tfm --- “type1” + -------------------------------------------------------------------- end +loadmodule"font-pfb.lua" -local anum_specification = { - { - type = "substitution", - features = { arab = { far = true, urd = true, snd = true } }, - data = anum_persian, - flags = { }, - valid = valid, - }, - { - type = "substitution", - features = { arab = { ["*"] = true } }, - data = anum_arabic, - flags = { }, - valid = valid, - }, -} +loadmodule"font-nms.lua" +loadmodule"font-clr.lua" +loadmodule"font-ltx.lua" + +create_callback("luaotfload.patch_font", "simple", dummy_function) -fonts.handlers.otf.addfeature("anum",anum_specification) % \end{macrocode} % -% we provide a callback for patching fonts on the fly, to be used by other -% packages. +% 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. +% 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. % -% \begin{macrocode} -luatexbase.create_callback("luaotfload.patch_font", "simple", function() end) -% \end{macrocode} +% 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 function deffont(...) - local fontdata = fonts.definers.read(...) - if type(fontdata) == "table" then - luatexbase.call_callback("luaotfload.patch_font", fontdata) +local define_font_wrapper = function (...) + --- we use “tfmdata” (not “fontdata”) for consistency with the + --- font loader + local tfmdata = fonts.definers.read(...) + if type(tfmdata) == "table" and tfmdata.shared then + local metadata = tfmdata.shared.rawdata.metadata + local mathdata = metadata.math --- do all fonts have this field? + if mathdata then + local mathconstants = { } --- why new hash, not modify in place? + local units_per_em = metadata.units_per_em + local size = tfmdata.size + for k,v in next, mathdata do + --- afaics this is alread taken care of by + --- definers.read + if stringfind(k, "Percent") then + -- keep percent values as is + print(k,v) + mathconstants[k] = v + else + mathconstants[k] = v / units_per_em * size + end + end + --- for \overwithdelims + --- done by definers.read as well + mathconstants.FractionDelimiterSize = 1.01 * size + --- fontloader has 2.4 × size + mathconstants.FractionDelimiterDisplayStyleSize = 2.39 * size + tfmdata.MathConstants = mathconstants + end + call_callback("luaotfload.patch_font", tfmdata) end - return fontdata + return tfmdata end + % \end{macrocode} % -% Finally we register the callbacks +% We provide a simplified version of the original font definition +% callback. % % \begin{macrocode} -local handler = nodes.simple_font_handler -luatexbase.reset_callback("define_font") -luatexbase.add_to_callback("pre_linebreak_filter", handler, "luaotfload") -luatexbase.add_to_callback("hpack_filter", handler, "luaotfload") -luatexbase.add_to_callback("define_font", deffont, "luaotfload") +local patch_defined_font = function (...) + local tfmdata = fonts.definers.read(...) + 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") + +if luaotfload.font_definer == "old" then + add_to_callback("define_font", + old_define_font_wrapper, + "luaotfload.define_font", + 1) +elseif luaotfload.font_definer == "generic" then + add_to_callback("define_font", + generic_context.callback_define_font, + "luaotfload.define_font", + 1) +elseif luaotfload.font_definer == "patch" then + add_to_callback("define_font", + patch_defined_font, + "luaotfload.define_font", + 1) +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} % % \iffalse -- cgit v1.2.3