You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.0 KiB
138 lines
4.0 KiB
-----------------------------------------------------------------------
|
|
-- FILE: luaotfload-fallback.lua
|
|
-- DESCRIPTION: part of luaotfload / fallback
|
|
-----------------------------------------------------------------------
|
|
|
|
local ProvidesLuaModule = {
|
|
name = "luaotfload-fallback",
|
|
version = "3.14", --TAGVERSION
|
|
date = "2020-05-06", --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 % This is set when the first font is loaded.
|
|
|
|
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] .. ';-fallback', 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
|
|
lookup[-i] = f -- Needed for multiscript interactions
|
|
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: inherited fonts (combining accents etc.)
|
|
local 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)
|
|
define_font = define_font or luaotfload.define_font -- Lazy loading because this file get's loaded before define_font is defined
|
|
if fonts == nil then
|
|
fonts = name
|
|
name = #fallback_table_fontnames + 1
|
|
else
|
|
name = name:lower()
|
|
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,
|
|
-- }
|
|
}
|
|
|
|
return {
|
|
process = dofallback,
|
|
}
|
|
--- vim:sw=2:ts=2:expandtab:tw=71
|
|
|