summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luaotfload/luaotfload-fakesc.lua
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-01-17 03:02:33 +0000
committerNorbert Preining <norbert@preining.info>2021-01-17 03:02:33 +0000
commit8591b56496b93eed20f638ee1ce46b11c3f7be58 (patch)
treeb2afe58ae1a4b7b138a752410d3d7232485a4f9d /macros/luatex/generic/luaotfload/luaotfload-fakesc.lua
parent07a2495c5aecc2f871625ae63d25ee1cc18b2ca5 (diff)
CTAN sync 202101170302
Diffstat (limited to 'macros/luatex/generic/luaotfload/luaotfload-fakesc.lua')
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-fakesc.lua204
1 files changed, 204 insertions, 0 deletions
diff --git a/macros/luatex/generic/luaotfload/luaotfload-fakesc.lua b/macros/luatex/generic/luaotfload/luaotfload-fakesc.lua
new file mode 100644
index 0000000000..421f6fd24d
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-fakesc.lua
@@ -0,0 +1,204 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-fakesc.lua
+-- DESCRIPTION: part of luaotfload / fakesc
+-----------------------------------------------------------------------
+
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
+ name = "luaotfload-fakesc",
+ version = "3.17", --TAGVERSION
+ date = "2021-01-08", --TAGDATE
+ description = "luaotfload submodule / fakesc",
+ license = "GPL v2.0",
+ author = "Marcel Krüger"
+}
+
+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 sep = lpeg.P' '^0 * ';' * lpeg.P' '^0
+local codepoint = lpeg.S'0123456789ABCDEF'^4/function(c)return tonumber(c, 16)end
+local codepoint_range = codepoint * ('..' * codepoint + lpeg.Cc(false))
+local function multirawset(table, key1, key2, value)
+ for key = key1,(key2 or key1) do
+ rawset(table, key, value)
+ end
+ return table
+end
+local script_extensions do
+ local entry = lpeg.Cg(codepoint_range * sep * lpeg.Ct((lpeg.C(lpeg.R'AZ' * lpeg.R'az'^1))^1 * ' ') * '#')^-1 * (1-lpeg.P'\n')^0 * '\n'
+ local file = lpeg.Cf(
+ lpeg.Ct''
+ * entry^0
+ , multirawset)
+
+ local f = io.open(kpse.find_file"ScriptExtensions.txt")
+ script_extensions = file:match(f:read'*a')
+ f:close()
+ for cp,t in next, script_extensions do
+ for i=1,#t do
+ t[t[i]] = true
+ end
+ end
+end
+local script_mapping do
+ -- We could extract these from PropertyValueAliases.txt...
+ local script_aliases = {
+ Adlam = "Adlm", Caucasian_Albanian = "Aghb", Ahom = "Ahom", Arabic = "Arab",
+ Imperial_Aramaic = "Armi", Armenian = "Armn", Avestan = "Avst",
+ Balinese = "Bali", Bamum = "Bamu", Bassa_Vah = "Bass", Batak = "Batk",
+ Bengali = "Beng", Bhaiksuki = "Bhks", Bopomofo = "Bopo", Brahmi = "Brah",
+ Braille = "Brai", Buginese = "Bugi", Buhid = "Buhd", Chakma = "Cakm",
+ Canadian_Aboriginal = "Cans", Carian = "Cari", Cham = "Cham",
+ Cherokee = "Cher", Coptic = "Copt", Cypriot = "Cprt", Cyrillic = "Cyrl",
+ Devanagari = "Deva", Dogra = "Dogr", Deseret = "Dsrt", Duployan = "Dupl",
+ Egyptian_Hieroglyphs = "Egyp", Elbasan = "Elba", Elymaic = "Elym",
+ Ethiopic = "Ethi", Georgian = "Geor", Glagolitic = "Glag",
+ Gunjala_Gondi = "Gong", Masaram_Gondi = "Gonm", Gothic = "Goth",
+ Grantha = "Gran", Greek = "Grek", Gujarati = "Gujr", Gurmukhi = "Guru",
+ Hangul = "Hang", Han = "Hani", Hanunoo = "Hano", Hatran = "Hatr",
+ Hebrew = "Hebr", Hiragana = "Hira", Anatolian_Hieroglyphs = "Hluw",
+ Pahawh_Hmong = "Hmng", Nyiakeng_Puachue_Hmong = "Hmnp",
+ Katakana_Or_Hiragana = "Hrkt", Old_Hungarian = "Hung", Old_Italic = "Ital",
+ Javanese = "Java", Kayah_Li = "Kali", Katakana = "Kana",
+ Kharoshthi = "Khar", Khmer = "Khmr", Khojki = "Khoj", Kannada = "Knda",
+ Kaithi = "Kthi", Tai_Tham = "Lana", Lao = "Laoo", Latin = "Latn",
+ Lepcha = "Lepc", Limbu = "Limb", Linear_A = "Lina", Linear_B = "Linb",
+ Lisu = "Lisu", Lycian = "Lyci", Lydian = "Lydi", Mahajani = "Mahj",
+ Makasar = "Maka", Mandaic = "Mand", Manichaean = "Mani", Marchen = "Marc",
+ Medefaidrin = "Medf", Mende_Kikakui = "Mend", Meroitic_Cursive = "Merc",
+ Meroitic_Hieroglyphs = "Mero", Malayalam = "Mlym", Modi = "Modi",
+ Mongolian = "Mong", Mro = "Mroo", Meetei_Mayek = "Mtei", Multani = "Mult",
+ Myanmar = "Mymr", Nandinagari = "Nand", Old_North_Arabian = "Narb",
+ Nabataean = "Nbat", Newa = "Newa", Nko = "Nkoo", Nushu = "Nshu",
+ Ogham = "Ogam", Ol_Chiki = "Olck", Old_Turkic = "Orkh", Oriya = "Orya",
+ Osage = "Osge", Osmanya = "Osma", Palmyrene = "Palm", Pau_Cin_Hau = "Pauc",
+ Old_Permic = "Perm", Phags_Pa = "Phag", Inscriptional_Pahlavi = "Phli",
+ Psalter_Pahlavi = "Phlp", Phoenician = "Phnx", Miao = "Plrd",
+ Inscriptional_Parthian = "Prti", Rejang = "Rjng", Hanifi_Rohingya = "Rohg",
+ Runic = "Runr", Samaritan = "Samr", Old_South_Arabian = "Sarb",
+ Saurashtra = "Saur", SignWriting = "Sgnw", Shavian = "Shaw",
+ Sharada = "Shrd", Siddham = "Sidd", Khudawadi = "Sind", Sinhala = "Sinh",
+ Sogdian = "Sogd", Old_Sogdian = "Sogo", Sora_Sompeng = "Sora",
+ Soyombo = "Soyo", Sundanese = "Sund", Syloti_Nagri = "Sylo",
+ Syriac = "Syrc", Tagbanwa = "Tagb", Takri = "Takr", Tai_Le = "Tale",
+ New_Tai_Lue = "Talu", Tamil = "Taml", Tangut = "Tang", Tai_Viet = "Tavt",
+ Telugu = "Telu", Tifinagh = "Tfng", Tagalog = "Tglg", Thaana = "Thaa",
+ Thai = "Thai", Tibetan = "Tibt", Tirhuta = "Tirh", Ugaritic = "Ugar",
+ Vai = "Vaii", Warang_Citi = "Wara", Wancho = "Wcho", Old_Persian = "Xpeo",
+ Cuneiform = "Xsux", Yi = "Yiii", Zanabazar_Square = "Zanb",
+ Inherited = "Zinh", Common = "Zyyy", Unknown = "Zzzz",
+ }
+ local entry = lpeg.Cg(codepoint_range * sep * ((lpeg.R'AZ' + lpeg.R'az' + '_')^1/script_aliases))^-1 * (1-lpeg.P'\n')^0 * '\n'
+ -- local entry = lpeg.Cg(codepoint_range * sep * lpeg.Cc(true))^-1 * (1-lpeg.P'\n')^0 * '\n'
+ local file = lpeg.Cf(
+ lpeg.Ct''
+ * entry^0
+ , multirawset)
+
+ local f = io.open(kpse.find_file"Scripts.txt")
+ script_mapping = file:match(f:read'*a')
+ f:close()
+end
+
+local additional_scripts_tables = { }
+
+local additional_scripts_fonts = setmetatable({}, {
+ __index = function(t, fid)
+ local f = font.getfont(fid)
+ -- table.tofile('myfont2', f)
+ local res = f and f.additional_scripts or false
+ t[fid] = res
+ return res
+ end,
+})
+
+local function makecombifont(tfmdata, _, additional_scripts)
+ local basescript = tfmdata.properties.script
+ local scripts = {basescript = false}
+ additional_scripts = additional_scripts_tables[additional_scripts]
+ for script, fontname in pairs(additional_scripts) do
+ if script ~= basescript then
+ local f = fonts.definers.read(fontname, tfmdata.size)
+ local fid
+ if type(f) == 'table' then
+ fid = font.define(f)
+ else
+ error[[FIXME???]]
+ end
+ scripts[script] = {
+ fid = fid,
+ font = f,
+ characters = f.characters,
+ }
+ end
+ end
+ tfmdata.additional_scripts = scripts
+end
+
+local glyph_id = node.id'glyph'
+-- TODO: unset last_script, matching parentheses etc
+function domultiscript(head, _, _, _, direction)
+ head = node.direct.todirect(head)
+ local last_fid, last_fonts, last_script
+ for cur, cid, fid in traverse_char(head) do
+ if fid ~= last_fid then
+ last_fid, last_fonts, last_script = fid, additional_scripts_fonts[fid]
+ end
+ if last_fonts then
+ local mapped_scr = script_mapping[cid]
+ if mapped_scr == "Zinh" then
+ mapped_scr = last_script
+ else
+ local additional_scr = script_extensions[cid]
+ if additional_scripts then
+ if additional_scripts[last_script] then
+ mapped_scr = last_script
+ elseif not last_fonts[mapped_scr] then
+ for i = 1, #additional_scripts do
+ if last_fonts[additional_scripts[i]] then
+ mapped_scr = additional_scripts[i]
+ break
+ end
+ end
+ end
+ elseif mapped_scr == "Zyyy" then
+ mapped_scr = last_script
+ end
+ end
+ last_script = mapped_scr
+ local mapped_font = last_fonts[mapped_scr]
+ if mapped_font then
+ setfont(cur, mapped_font.fid)
+ end
+ end
+ end
+end
+
+function luaotfload.add_multiscript(name, fonts)
+ if fonts == nil then
+ fonts = name
+ name = #additional_scripts_fonts + 1
+ end
+ additional_scripts_tables[name] = fonts
+ return name
+end
+
+otffeatures.register {
+ name = "multiscript",
+ description = "Combine fonts for multiple scripts",
+ manipulators = {
+ node = makecombifont,
+ },
+ -- processors = { -- processors would be nice, but they are applied
+ -- -- too late for our purposes
+ -- node = donotdef,
+ -- }
+}
+
+--- vim:sw=2:ts=2:expandtab:tw=71