[latex3-commits] [git/LaTeX3-latex3-luaotfload] dev: Interpret script and language as OpenType tags (77a9655)

Marcel Fabian Krüger tex at 2krueger.de
Sat Nov 9 03:08:14 CET 2019


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

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

commit 77a96554d4585cd784f1586d65586b7ea8963921
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date:   Fri Nov 8 17:58:07 2019 +0100

    Interpret script and language as OpenType tags


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

77a96554d4585cd784f1586d65586b7ea8963921
 src/luaotfload-harf-define.lua | 24 ++++++++---
 src/luaotfload-harf-plug.lua   |  7 +---
 src/luaotfload-scripts.lua     | 91 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/src/luaotfload-harf-define.lua b/src/luaotfload-harf-define.lua
index e8154cb..eb5da49 100644
--- a/src/luaotfload-harf-define.lua
+++ b/src/luaotfload-harf-define.lua
@@ -23,6 +23,7 @@ local stringupper = string.upper
 local gsub = string.gsub
 
 local hb = luaotfload.harfbuzz
+local scriptlang_to_harfbuzz = require'luaotfload-scripts'.to_harfbuzz
 
 local hbfonts = {}
 
@@ -32,6 +33,9 @@ local os2tag  = hb.Tag.new("OS/2")
 local posttag = hb.Tag.new("post")
 local glyftag = hb.Tag.new("glyf")
 
+local invalid_l         = hb.Language.new()
+local invalid_s         = hb.Script.new()
+
 local containers = luaotfload.fontloader.containers
 local hbcacheversion = 1.0
 local facecache = containers.define("fonts", "hb", hbcacheversion, true)
@@ -366,15 +370,23 @@ fonts.readers.harf = function(spec)
   local hb_features = {}
   spec.hb_features = hb_features
 
-  if rawfeatures.language then
+  if rawfeatures.script then
+    local script = stringlower(rawfeatures.script)
+    if script == "dflt" then -- Probably a noop, HarfBuzz normalizes anyway
+      script = "DFLT"
+    end
+    local language = stringupper(rawfeatures.language or 'dflt')
+    language = language == "DFLT" and "dflt" or language
+    local hb_script, hb_lang = scriptlang_to_harfbuzz(script, language)
+    spec.script, spec.language = hb.Script.new(hb_script), hb.Language.new(hb_lang)
+  elseif rawfeatures.language then
     local language = stringupper(rawfeatures.language)
     spec.language = hb.Language.new(language == "DFLT" and "dflt"
                                                         or language)
-  end
-  if rawfeatures.script then
-    local script = stringlower(rawfeatures.script)
-    spec.script = hb.Script.new(script == "dflt" and "DFLT"
-                                                  or script)
+    spec.script = invalid_s
+  else
+    spec.script = invalid_s
+    spec.language = invalid_l
   end
   for key, val in next, rawfeatures do
     if key:len() == 4 then
diff --git a/src/luaotfload-harf-plug.lua b/src/luaotfload-harf-plug.lua
index 123a1c4..dfbe7b8 100644
--- a/src/luaotfload-harf-plug.lua
+++ b/src/luaotfload-harf-plug.lua
@@ -98,9 +98,6 @@ local italiccorr_t      = 3
 local regulardisc_t     = 3
 local spaceskip_t       = 13
 
-local invalid_l         = hb.Language.new()
-local invalid_s         = hb.Script.new()
-
 local dir_ltr           = hb.Direction.new("ltr")
 local dir_rtl           = hb.Direction.new("rtl")
 local fl_unsafe         = hb.Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK
@@ -322,8 +319,8 @@ function shape(head, node, run)
   local hbshared = hbdata.shared
   local hbfont = hbshared.font
 
-  local lang = spec.language or invalid_l
-  local script = spec.script or invalid_s
+  local lang = spec.language
+  local script = spec.script
   local shapers = options.shaper and { options.shaper } or {}
 
   local buf = hb.Buffer.new()
diff --git a/src/luaotfload-scripts.lua b/src/luaotfload-scripts.lua
new file mode 100644
index 0000000..16e5df0
--- /dev/null
+++ b/src/luaotfload-scripts.lua
@@ -0,0 +1,91 @@
+-----------------------------------------------------------------------
+--         FILE:  luaotfload-script.lua
+--  DESCRIPTION:  part of luaotfload / script
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = { 
+    name          = "luaotfload-script",
+    version       = "3.1",       --TAGVERSION
+    date          = "2019-11-04", --TAGDATE
+    description   = "luaotfload submodule / Script helpers",
+    license       = "CC0 1.0 Universal",
+    author        = "Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+  luatexbase.provides_module (ProvidesLuaModule)
+end  
+
+local canonical_name = {
+  dflt = "DFLT",
+  hira = "kana",
+  laoo = "lao",
+  yiii = "yi",
+  nkoo = "nko",
+  yaii = "vai",
+  ["lao "] = "lao",
+  ["yi  "] = "yi",
+  ["nko "] = "nko",
+  ["vai "] = "vai",
+}
+local versioned_script = {
+  mym = "mymr", mymr = "mym",
+  bng = "beng", beng = "bng",
+  dev = "deva", deva = "dev",
+  gjr = "gujr", gujr = "gjr",
+  gur = "guru", guru = "gur",
+  knd = "knda", knda = "knd",
+  mlm = "mlym", mlym = "mlm",
+  ory = "orya", orya = "ory",
+  tml = "taml", taml = "tml",
+  tel = "telu", telu = "tel",
+}
+local function get_versioned(original)
+  local base = original:gsub("%d$", "") -- Strip any existing version
+  local versioned = versioned_script[base]
+  if not versioned then
+    return original
+  end
+  if #base == 3 then
+    local t = base
+    base = versioned
+    versioned = t
+  end
+  if base == "mymr" then
+    return "mym2", "mymr"
+  end
+  return versioned .. '3', versioned .. '2', base
+end
+
+-- We never return trailing spaces because I consider them implementation details.
+local function script_to_ot(iso)
+  iso = iso:lower()
+  return get_versioned(canonical_name[iso] or iso)
+end
+
+local function script_to_iso(tag)
+  tag = tag:lower()
+  tag = canonical_name[tag] or tag
+  local stripped, did_strip = tag:gsub("%d$", "")
+  tag = did_strip and versioned_script[stripped] or tag
+  local tag_length = #tag
+  if tag_length == 4 then return tag end -- Optimization for common case
+  -- I promise you, I am not making this one up
+  return tag .. string.rep(tag:sub(tag_length, tag_length), 4-tag_length)
+end
+
+local function to_harfbuzz(script, language)
+  local otscript = script_to_iso(script)
+  if script_to_ot(otscript) == script then
+    return otscript, language
+  end
+  return otscript, "x-hbot" .. script .. "-hbsc" .. language
+end
+
+return {
+  to_harfbuzz = to_harfbuzz,
+  script = {
+    to_ot = script_to_ot,
+    to_iso = script_to_iso,
+  },
+}





More information about the latex3-commits mailing list