From f48b1743185bb89337a9c8224ba05628c106128e Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg42.2a@gmail.com>
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

