[latex3-commits] [git/LaTeX3-latex3-luaotfload] dev: Initial implementation for fallback fonts (ee8e753)

Marcel Fabian Krüger tex at 2krueger.de
Thu Dec 19 03:43:13 CET 2019


Repository : https://github.com/latex3/luaotfload
On branch  : dev
Link       : https://github.com/latex3/luaotfload/commit/ee8e753708345fa0da9b8a60bad94efae165a8d4

>---------------------------------------------------------------

commit ee8e753708345fa0da9b8a60bad94efae165a8d4
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date:   Thu Dec 19 03:43:13 2019 +0100

    Initial implementation for fallback fonts


>---------------------------------------------------------------

ee8e753708345fa0da9b8a60bad94efae165a8d4
 src/luaotfload-fallback.lua | 146 ++++++++++++++++++++++++++++++++++++++++++++
 src/luaotfload-filelist.lua |   1 +
 src/luaotfload-init.lua     |   1 +
 src/luaotfload-main.lua     |   1 +
 4 files changed, 149 insertions(+)

diff --git a/src/luaotfload-fallback.lua b/src/luaotfload-fallback.lua
new file mode 100644
index 0000000..fdff839
--- /dev/null
+++ b/src/luaotfload-fallback.lua
@@ -0,0 +1,146 @@
+-----------------------------------------------------------------------
+--         FILE:  luaotfload-fallback.lua
+--  DESCRIPTION:  part of luaotfload / fallback
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+    name          = "luaotfload-fallback",
+    version       = "3.1201-dev",     --TAGVERSION
+    date          = "2019-11-14", --TAGDATE
+    description   = "luaotfload submodule / fallback",
+    license       = "GPL v2.0",
+    author        = "Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+  luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local nodenew            = node.direct.new
+local getfont            = font.getfont
+local setfont            = node.direct.setfont
+local getwhd             = node.direct.getwhd
+local insert_after       = node.direct.insert_after
+local traverse_char      = node.direct.traverse_char
+local protect_glyph      = node.direct.protect_glyph
+local otffeatures        = fonts.constructors.newfeatures "otf"
+-- local normalize          = fonts.handlers.otf.features.normalize
+local definers           = fonts.definers
+local define_font        = luaotfload.define_font
+
+local fallback_table_fontnames = {}
+
+local fallback_table = setmetatable({}, {
+  __index = function(t, name)
+    local names = fallback_table_fontnames[name]
+    if not names then 
+      t[name] = false
+      return false
+    end
+    local res = setmetatable({}, {
+      __index = function(tt, size)
+        local lookup = {}
+        for i=#names,1,-1 do
+          local f = define_font(names[i], size)
+          local fid
+          if type(f) == 'table' then
+            fid = font.define(f)
+            definers.register(f, fid)
+          elseif f then
+            fid = f
+            f = font.getfont(fid)
+          end
+          for uni, _ in next, f.characters do
+            rawset(lookup, uni, fid)
+          end
+        end
+        local lookup = {}
+        for i=#names,1,-1 do
+          local f = define_font(names[i], size)
+          local fid
+          if type(f) == 'table' then
+            fid = font.define(f)
+            definers.register(f, fid)
+          elseif f then
+            fid = f
+            f = font.getfont(fid)
+          end
+          for uni, _ in next, f.characters do
+            rawset(lookup, uni, fid)
+          end
+        end
+        tt[size] = lookup
+        return lookup
+      end,
+    })
+    t[name] = res
+    return res
+  end,
+})
+
+local fallback_lookups = setmetatable({}, {
+  __index = function(t, fid)
+    local f = font.getfont(fid)
+    -- table.tofile('myfont2', f)
+    local res = f and f.fallback_lookup or false
+    if res then
+      res = table.merged(res)
+      for uni in next, f.characters do
+        rawset(res, uni, nil)
+      end
+    end
+    t[fid] = res
+    return res
+  end,
+})
+
+local function makefallbackfont(tfmdata, _, fallback)
+  local t = fallback_table[fallback]
+  if not t then error(string.format("Unknown fallback table %s", fallback)) end
+  fallback = t[tfmdata.size]
+  local fallback_lookup = {}
+  tfmdata.fallback_lookup = fallback
+end
+
+local glyph_id = node.id'glyph'
+-- TODO: unset last_script, matching parentheses etc
+function dofallback(head, _, _, _, direction)
+  head = node.direct.todirect(head)
+  local last_fid, last_fallbacks
+  for cur, cid, fid in traverse_char(head) do
+    if fid ~= last_fid then
+      last_fid, last_fallbacks = fid, fallback_lookups[fid]
+    end
+    if last_fallbacks then
+      local new_fid = last_fallbacks[cid]
+      if new_fid then
+        setfont(cur, new_fid)
+      end
+    end
+  end
+end
+
+function luaotfload.add_fallback(name, fonts)
+  if fonts == nil then
+    fonts = name
+    name = #additional_scripts_fonts + 1
+  end
+  fallback_table_fontnames[name] = fonts
+  fallback_table[name] = nil
+  return name
+end
+
+otffeatures.register {
+  name        = "fallback",
+  description = "Fill in missing glyphs from other fonts",
+  manipulators = {
+    node = makefallbackfont,
+    plug = makefallbackfont,
+  },
+  -- processors = { -- processors would be nice, but they are applied
+  --                -- too late for our purposes
+  --   node = donotdef,
+  -- }
+}
+
+--- vim:sw=2:ts=2:expandtab:tw=71
diff --git a/src/luaotfload-filelist.lua b/src/luaotfload-filelist.lua
index 5d07971..3b115b0 100644
--- a/src/luaotfload-filelist.lua
+++ b/src/luaotfload-filelist.lua
@@ -252,6 +252,7 @@ luaotfload.filelist.data =
     { name = "harf-plug"         ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
     { name = "loaders"           ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, 
     { name = "multiscript"       ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, 
+    { name = "fallback"          ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, 
     { name = "parsers"           ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, 
     { name = "resolvers"         ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, 
     { name = "unicode"           ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
diff --git a/src/luaotfload-init.lua b/src/luaotfload-init.lua
index 1f8655f..8812a87 100644
--- a/src/luaotfload-init.lua
+++ b/src/luaotfload-init.lua
@@ -439,6 +439,7 @@ local init_post_install_callbacks = function ()
       direction = tex.get'textdir'
     end
     domultiscript(head, nil, nil, nil, direction)
+    dofallback(head, nil, nil, nil, direction)
     return handler(head, groupcode, nil, nil, direction)
   end
   luatexbase.add_to_callback("pre_linebreak_filter",
diff --git a/src/luaotfload-main.lua b/src/luaotfload-main.lua
index d1d036f..ca4216b 100644
--- a/src/luaotfload-main.lua
+++ b/src/luaotfload-main.lua
@@ -327,6 +327,7 @@ luaotfload.main = function ()
     end
     initialize "auxiliary"    --- additional high-level functionality
     loadmodule "multiscript"  --- ...
+    loadmodule "fallback"  --- ...
     loadmodule "tounicode"
 
     luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec





More information about the latex3-commits mailing list