[latex3-commits] [l3svn] branch master updated: Switch to luaotfload in format mode

noreply at latex-project.org noreply at latex-project.org
Sat Feb 18 18:21:43 CET 2017


This is an automated email from the git hooks/post-receive script.

joseph pushed a commit to branch master
in repository l3svn.

The following commit(s) were added to refs/heads/master by this push:
       new  3721513   Switch to luaotfload in format mode
3721513 is described below

commit 37215133e487dee495efa6955f24016b50e3e537
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Sat Feb 18 17:20:03 2017 +0000

    Switch to luaotfload in format mode
    
    As LaTeX2e has gone this way it makes sense and means we can
    potentially load a full family of fonts in format mode without
    messing about. This also means some generic Lua is available which
    may be useful.
    
    Note that the font loading itself probably needs a little work: we
    now can do things 'properly' or at least as well as 2e can do them,
    just need to set up a bit more of the mechanisms.
---
 l3kernel/fontloader.lua |  290 -----------------------------------------------
 l3kernel/l3alloc.dtx    |   24 ++++
 l3kernel/l3format.ins   |    2 +-
 l3kernel/l3luatex.dtx   |   91 +++------------
 4 files changed, 40 insertions(+), 367 deletions(-)

diff --git a/l3kernel/fontloader.lua b/l3kernel/fontloader.lua
deleted file mode 100644
index acc9a4b..0000000
--- a/l3kernel/fontloader.lua
+++ /dev/null
@@ -1,290 +0,0 @@
---- The fontloader uses the LuaTeX internal fontforge library (called
---- fontloader) to inspect an OpenType, a TrueType or a Type1 font. It
---- converts this font to a font structure  TeX uses internally.
---
---  fontloader.lua
---  speedata publisher
---
---  Copyright 2010-2011 Patrick Gundlach.
---  See file COPYING in the root directory for license info.
-
-
-module(...,package.seeall)
-
---- Return `truetype`, `opentype` or `type1` depending on the string
---- `filename`. If not recognized form  the file name, return _nil_.
---- This function simply looks at the last three letters.
-function guess_fonttype( filename )
-    local f=filename:lower()
-    if f:match(".*%.ttf$") then return "truetype"
-    elseif f:match(".*%.otf$") then return "opentype"
-    elseif f:match(".*%.pfb$") then return "type1"
-    else return nil
-    end
-end
-
---- Return `true` if the this feature table `tab` has an entry for the
---- given `script` and `lang`. The table is something like:
----
----     [1] = {
----       ["langs"] = {
----         [1] = "AZE "
----         [2] = "CRT "
----         [3] = "TRK "
----       },
----       ["script"] = "latn"
----     },
-function features_scripts_matches( tab,script,lang )
-    local lang   = string.lower(lang)
-    local script = string.lower(script)
-    for i=1,#tab do
-        local entry = tab[i]
-        if string.lower(entry.script)==script then
-            for j=1,#entry.langs do
-                if string.lower(entry.langs[j])==lang then
-                    return true
-                end
-            end
-        end
-    end
-    return false
-end
-
---- Convert codepoint to a UTF-16 string.
-function to_utf16(codepoint)
-    assert(codepoint)
-    if codepoint < 65536 then
-        return string.format("%04X",codepoint)
-    else
-        return string.format("%04X%04X",codepoint / 1024 + 0xD800 ,codepoint % 1024 + 0xDC00)
-    end
-end
-
---- Return the string that is responsible for the OpenType feature `featurename`.
---- Currently only lookups are for script `latn` and language `dflt`.
-function find_feature_string(f,featurename)
-    local ret = {}
-    if f.gsub==nil then
-        return ret
-    end
-    for i=1,#f.gsub do
-        local gsub_tabelle=f.gsub[i]
-        if gsub_tabelle.features then
-            for j = 1,#gsub_tabelle.features do
-                local gtf = gsub_tabelle.features[j]
-                if gtf.tag==featurename and features_scripts_matches(gtf.scripts,"latn","dflt") then
-                    if #gsub_tabelle.subtables ~= 1 then
-                        -- w("warning: #subtables in gpos != 1")
-                    end
-                    ret[#ret + 1] = gsub_tabelle.subtables[1].name
-                end
-            end
-        end
-    end
-    return ret
-end
-
---- LuaTeX's fontloader (function `to_table()`) returns a rather complex table
---- with all kinds of information. Loading this table is expensive (_todo:
---- measure it_), so we  don't load it over and over agin if the user
---- requests the same font in a different size. We also cache  the `to_unicode` mapping.
---- Only the size dependent values are computed.
-local lookup_fonttable_from_filename = {}
-
-
---- For define_font() we extend our file list
-local fontlist = {}
-
-local fp = os.getenv("SP_FONT_PATH")
-if fp ~= "" then
-  for _,dir in ipairs(string.explode(fp,":")) do
-    for i in dirtree(dir) do
-      local filename = i:gsub(".*/([^/]+)$","%1")
-      fontlist[filename] = i
-    end
-  end
-end
-
-
-
---- Return a TeX usable font table, or _nil_ plus an error message.
---- The parameter `name` is the filename (without path), `size` is
---- given in scaled points, `extra_parameter` is a table such as:
----     {
----       ["space"] = "25"
----       ["marginprotrusion"] = "100"
----       ["otfeatures"] = {
----         ["smcp"] = "true"
----       },
----     },
-function define_font(name, size,extra_parameter)
-    local extra_parameter = extra_parameter or {}
-    local fonttable
-
-    if lookup_fonttable_from_filename[name] then
-        fonttable=lookup_fonttable_from_filename[name]
-        assert(fonttable)
-    else
-        -- These are stored in the cached fonttable table
-        local filename_with_path
-        local lookup_codepoint_by_name   = {}
-        local lookup_codepoint_by_number = {}
-
-        filename_with_path = kpse.filelist[name] or fontlist[name]
-        if not filename_with_path then return false, string.format("Fontfile '%s' not found.", name) end
-        local font, err = fontloader.open(filename_with_path)
-        if not font then
-            if type(err) == "string" then
-                return false, err
-            else
-                printtable("Font error",err)
-            end
-        end
-        fonttable = fontloader.to_table(font)
-        if fonttable == nil then return false, string.format("Problem while loading font '%s'",tostring(filename_with_path))  end
-
-        -- Store the table for quicker lookup later.
-        lookup_fonttable_from_filename[name]=fonttable
-
-        fonttable.filename_with_path = filename_with_path
-        local is_unicode = (fonttable.pfminfo.unicoderanges ~= nil)
-
-        --- We require a mapping glyph number -> unicode codepoint. The problem is
-        --- that TTF/OTF fonts have a different encoding mechanism. TTF/OTF can be
-        --- accessed via the table `fonttable.map.backmap` (the key is the glyph
-        --- number, the value is glyph name). For Type 1 fonts we use
-        --- `glyph.unicode` and `glyph.name` for the codepoint and the name.
-        ---
-        --- For kerning a mapping glyphname -> codepoint is needed.
-        if is_unicode then
-            -- TTF/OTF, use map.backmap
-            for i = 1,#fonttable.glyphs do
-                local g=fonttable.glyphs[i]
-                lookup_codepoint_by_name[g.name] = fonttable.map.backmap[i]
-                lookup_codepoint_by_number[i]    = fonttable.map.backmap[i]
-            end
-        else
-            -- Type1, use glyph.unicode
-            for i = 1,#fonttable.glyphs do
-                local g=fonttable.glyphs[i]
-                lookup_codepoint_by_name[g.name] = g.unicode
-                lookup_codepoint_by_number[i]    = g.unicode
-            end
-        end -- is unicode
-        fonttable.lookup_codepoint_by_name   = lookup_codepoint_by_name
-        fonttable.lookup_codepoint_by_number = lookup_codepoint_by_number
-    end
-
-    --- A this point we have taken the `fonttable` from memory or from `fontloader#to_table()`. The next
-    --- part is mostly size/features dependent.
-
-    if (size < 0) then size = (- 655.36) * size end
-    -- Some fonts have `units_per_em` set to 0. I am not sure if setting this to
-    -- 1000 in that case has any drawbacks.
-    if fonttable.units_per_em == 0 then fonttable.units_per_em = 1000 end
-    local mag = size / fonttable.units_per_em
-
-    --- The table `f` is the font structure that TeX can use, see chapter 7 of the LuaTeX manual for a detailed description. This is returned from
-    --- the function. It is safe to store additional data here.
-    local f = { }
-
-    -- The index of the characters table must match the glyphs in the
-    -- "document". It is wise to have everything in unicode, so we do keep that
-    -- in mind when filling the characters subtable.
-    f.characters    = { }
-    f.fontloader    = fonttable
-    if extra_parameter and extra_parameter.otfeatures and extra_parameter.otfeatures.smcp then
-        f.smcp = find_feature_string(fonttable,"smcp")
-    end
-    if extra_parameter and extra_parameter.otfeatures and extra_parameter.otfeatures.onum then
-        f.onum = find_feature_string(fonttable,"onum")
-    end
-
-    f.otfeatures    = extra_parameter.otfeatures             -- OpenType Features (smcp,...)
-    f.name          = fonttable.fontname
-    f.fullname      = fonttable.fontname
-    f.designsize    = size
-    f.size          = size
-    f.direction     = 0
-    f.filename      = fonttable.filename_with_path
-    f.type          = 'real'
-    f.encodingbytes = 2
-    f.tounicode     = 1
-    f.stretch       = 40
-    f.shrink        = 30
-    f.step          = 10
-    f.auto_expand   = true
-
-    f.parameters    = {
-        slant         = 0,
-        space         = ( extra_parameter.space or 25 ) / 100  * size,
-        space_stretch = 0.3  * size,
-        space_shrink  = 0.1  * size,
-        x_height      = 0.4  * size,
-        quad          = 1.0  * size,
-        extra_space   = 0
-    }
-
-    f.format = guess_fonttype(name)
-    if f.format==nil then return false,"Could not determine the type of the font '".. fonttable.filename_with_path .."'." end
-
-    f.embedding = "subset"
-    f.cidinfo = fonttable.cidinfo
-
-
-    for i=1,#fonttable.glyphs do
-        local glyph     = fonttable.glyphs[i]
-        local codepoint = fonttable.lookup_codepoint_by_number[i]
-
-        -- TeX uses U+002D HYPHEN-MINUS for hyphen, correct would be U+2012 HYPHEN.
-        -- Because font vendors all have different ideas of hyphen, we just map all
-        -- occurrences of *HYPHEN* to 0x2D (decimal 45)
-        if glyph.name:lower():match("^hyphen$") then codepoint=45  end
-
-        f.characters[codepoint] = {
-            index = i,
-            width = glyph.width * mag,
-            name  = glyph.name,
-            expansion_factor = 1000,
-        }
-
-        -- Height and depth of the glyph
-        if glyph.boundingbox[4] then f.characters[codepoint].height = glyph.boundingbox[4] * mag  end
-        if glyph.boundingbox[2] then f.characters[codepoint].depth = -glyph.boundingbox[2] * mag  end
-
-        --- We change the `tounicode` entry for entries with a period. Sometimes fonts
-        --- have entries like `a.sc` or `a.c2sc` for smallcaps letter a. We are
-        --- only interested in the part before the period.
-        --- _This solution might not be perfect_.
-        if glyph.name:match("%.") then
-            local destname = glyph.name:gsub("^([^%.]*)%..*$","%1")
-            local cp = fonttable.lookup_codepoint_by_name[destname]
-            if cp then
-                f.characters[codepoint].tounicode=to_utf16(cp)
-            end
-        end
-
-
-        --- Margin protrusion is enabled in `spinit.lua`.
-        if (glyph.name=="hyphen" or glyph.name=="period" or glyph.name=="comma") and extra_parameter and type(extra_parameter.marginprotrusion) == "number" then
-            f.characters[codepoint]["right_protruding"] = glyph.width * extra_parameter.marginprotrusion / 100
-        end
-
-        --- We do kerning by default. In the future we could turn it off.
-        local kerns={}
-        if glyph.kerns then
-            for _,kern in pairs(glyph.kerns) do
-                local dest = fonttable.lookup_codepoint_by_name[kern.char]
-                if dest and dest > 0 then
-                    kerns[dest] = kern.off * mag
-                else
-                end
-            end
-        end
-        f.characters[codepoint].kerns = kerns
-    end
-
-    return true,f
-end
-
--- End of file
diff --git a/l3kernel/l3alloc.dtx b/l3kernel/l3alloc.dtx
index f0a3ac6..9be0886 100644
--- a/l3kernel/l3alloc.dtx
+++ b/l3kernel/l3alloc.dtx
@@ -116,6 +116,30 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}
+%   {
+%     \e at alloc@attribute at count ,
+%     \e at alloc@whatsit at count   ,
+%     \e at alloc@bytecode at count  ,
+%     \e at alloc@luachunk at count
+%   }
+%   To allow \LuaTeX{} to load |ltluatex.lua| for generic \Lua{} support, a
+%   small number of counts have to be correctly named at the \TeX{} level.
+%   At present there are no \pkg{expl3} allocators for these concepts so the
+%   numbers, \emph{etc.}, may well change here.
+%    \begin{macrocode}
+\etex_ifdefined:D \luatex_luatexversion:D
+  \group_begin:
+    \tex_catcode:D `\@ = 11 ~
+    \tex_global:D \tex_countdef:D \e at alloc@attribute at count = 21 ~
+    \tex_global:D \tex_countdef:D \e at alloc@whatsit at count   = 22 ~
+    \tex_global:D \tex_countdef:D \e at alloc@bytecode at count  = 23 ~
+    \tex_global:D \tex_countdef:D \e at alloc@luachunk at count  = 24 ~
+  \group_end:
+\tex_fi:D
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{macro}
 %   {\box_new:N, \dim_new:N, \int_new:N, \muskip_new:N \skip_new:N}
 %   Each of the public allocators is a wrapper around the one internal
diff --git a/l3kernel/l3format.ins b/l3kernel/l3format.ins
index e77e89e..cea3df3 100644
--- a/l3kernel/l3format.ins
+++ b/l3kernel/l3format.ins
@@ -126,6 +126,6 @@ Do not distribute a modified version of this file.
 \endpreamble
 \nopostamble
 \generate{\file{expl3.lua}   {\from{l3luatex.dtx}{lua,package}}}
-\generate{\file{l3format.lua}{\from{l3luatex.dtx}{fontloader}}}
+\generate{\file{l3format.lua}{\from{l3luatex.dtx}{lua,initex}}}
 
 \endbatchfile
diff --git a/l3kernel/l3luatex.dtx b/l3kernel/l3luatex.dtx
index efdcdb1..baef9af 100644
--- a/l3kernel/l3luatex.dtx
+++ b/l3kernel/l3luatex.dtx
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: l3luatex.dtx Copyright (C) 2010-2016 The LaTeX3 Project
+%% File: l3luatex.dtx Copyright (C) 2010-2017 The LaTeX3 Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -277,96 +277,35 @@ l3kernel.charcat = charcat
 %    \end{macrocode}
 % \end{macro}
 %
-%    \begin{macrocode}
-%</lua>
-%    \end{macrocode}
+% \subsection{Generic \Lua{} and font support}
 %
 %    \begin{macrocode}
-%</initex|package>
+%<*initex>
 %    \end{macrocode}
 %
-% \subsection{Format mode code: font loader}
-%
+% A small amount of generic code is used by almost all \LuaTeX{} material so
+% needs to be loaded by the format.
 %    \begin{macrocode}
-%<*fontloader>
+require("ltluatex")
 %    \end{macrocode}
 %
-% In format mode, there needs to be a font loader available to let us
-% use OpenType fonts. For testing, this is provided by
-% \texttt{fontloader.lua} from the Speedata Publisher system
-% (\url{https://github.com/speedata/publisher}). The code there is designed
-% to be self-contained and has a certain number of build-in assumptions,
-% so there is a small amount of compatibility required.
-% 
-% The code we load looks up \texttt{texmf} tree files using
-% \texttt{kpse.filelist}, which isn't part of the standard \texttt{kpse}
-% library. The interface is emulated using metatable.
+% With the above available the font loader code used by plain \TeX{} and
+% \LaTeXe{} when used with \LuaTeX{} can be loaded here. This is thus being
+% treated more-or-less as part of the engine itself.
 %    \begin{macrocode}
-kpse.filelist = setmetatable({}, {
-  __index = function (t, key)
-    return kpse.lookup(key)
-  end
-})
+require("luaotfload-main")
+local _void = luaotfload.main()
 %    \end{macrocode}
-% There is a built-in assumption in \texttt{fontloader.lua} that various
-% environmental variables are set. We deal with that by intercepting the
-% relevant names and returning something sane.
 %    \begin{macrocode}
-local os_getenv = os.getenv
-function os.getenv (var)
-  if var == "SP_FONT_PATH" then return "" end
-  return os_getenv(var)
-end
+%</initex>
 %    \end{macrocode}
-% As detailed in
-% \url{https://github.com/speedata/publisher/blob/develop/COPYING}, the current
-% license for Speedata Publisher is \textsc{AGPLv3}. We therefore only
-% load the file and use its public interfaces rather than copying/modifying
-% the code itself. Note though that we do have permission to use
-% \texttt{fontloader.lua} as a public domain work
-% (\url{http://chat.stackexchange.com/transcript/message/27273687#27273687}):
-% if we want to develop a richer loader we may want to take advantage of that
-% (which also applies to the simple shaper in the related \texttt{fonts.lua}
-% file).
-%    \begin{macrocode}
-local fontloader = require("fontloader.lua")
-%    \end{macrocode}
-% That done, register a callback which at present simply passes everything
-% through. There's no attempt to pick up font settings (which presumably
-% will be needed). Syntax is coerced to the same as for \XeTeX{}.
+%
 %    \begin{macrocode}
-callback.register("define_font", 
-  function (name, size, id)
-    local opts, opttab, otfeatures = "", { }, { }
-    if string.match(name, "^%[") then
-      name, opts = string.match(name, "^%[([^%]]*)%][^:]*:?(.*)")
-    end
-    if opts ~= "" then
-      for _,kv in ipairs(string.explode(opts,";")) do
-        if string.match(kv, "=") then
-          local k, v = string.match(kv, "([^=]*)=?(.*)")
-          opttab[k] = v
-        else
-          if string.match(kv, "^+") then
-            otfeatures[string.sub(kv,2,-1)] = "true"
-          elseif string.match(kv, "^-") then
-            otfeatures[string.sub(kv,2,-1)] = "false"
-          else
-            otfeatures[kv] = "true"
-          end
-        end
-      end
-    end
-    if next(otfeatures) then
-      opttab["otfeatures"] = otfeatures
-    end
-    return select(2, fontloader.define_font(name, size, opttab))
-  end
-)
+%</lua>
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-%</fontloader>
+%</initex|package>
 %    \end{macrocode}
 %
 %\end{implementation}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the latex3-commits mailing list