diff options
author | Philipp Gesang <phg@phi-gamma.net> | 2016-02-19 22:41:23 +0100 |
---|---|---|
committer | Philipp Gesang <phg@phi-gamma.net> | 2016-02-19 22:48:02 +0100 |
commit | 3447815896954281938500d49bedef715078a140 (patch) | |
tree | d41348716e437e223fcf30ae636c9bc32e645639 | |
parent | 9e04cce348b4de350b2e0612698c81311e6e6e9d (diff) | |
download | luaotfload-3447815896954281938500d49bedef715078a140.tar.gz |
[features,parsers] implement font fallbacks
Building on the combination mechanism, this allows defining fallback
fonts of which all glyphs are pulled that aren’t currently part of the
base font. Example:
\input luaotfload.sty
\font \lm = file:lmroman10-regular.otf:mode=base
\font \cmu = file:cmunrm.otf:mode=base
\font \lmu = "combo: 1->\fontid\lm; 2->\fontid\cmu,fallback"
\lmu Eh bien, mon prince. Gênes et Lueques ne sont plus que des
apanages, des поместья, de la famille Buonaparte.
\bye
This allows setting Latin Modern text that contains Cyrillic letters.
Note that -- as with the other combinations -- only glyphs are
considered, no other properties of the fallback font. So besides the
occasional letter in a different script this functionality is probably
useless.
-rw-r--r-- | src/luaotfload-features.lua | 56 | ||||
-rw-r--r-- | src/luaotfload-loaders.lua | 1 | ||||
-rw-r--r-- | src/luaotfload-parsers.lua | 9 |
3 files changed, 41 insertions, 25 deletions
diff --git a/src/luaotfload-features.lua b/src/luaotfload-features.lua index aeeaea3..4bcfbc3 100644 --- a/src/luaotfload-features.lua +++ b/src/luaotfload-features.lua @@ -100,9 +100,15 @@ local handle_combination = function (combo, spec) local fnt = fontidentifiers [id] if fnt then local chars = cur.chars - report ("both", 0, "load", - " *> %.2d: include font %d at rank %d (%d items).", - i, id, idx, (chars and #chars or 0)) + if chars == true then + report ("both", 0, "load", + " *> %.2d: fallback font %d at rank %d.", + i, id, idx) + else + report ("both", 0, "load", + " *> %.2d: include font %d at rank %d (%d items).", + i, id, idx, (chars and #chars or 0)) + end chain [#chain + 1] = { fnt, chars, idx = idx } fontids [#fontids + 1] = { id = id } else @@ -143,8 +149,12 @@ local handle_combination = function (combo, spec) local src = fnt.characters local cnt = 0 - local pickchr = function (uc) + local pickchr = function (uc, unavailable) local chr = src [uc] + if unavailable == true and basechar [uc] then + --- fallback mode: already known + return + end if chr then chr.commands = { { "slot", i, uc } } basechar [uc] = chr @@ -152,23 +162,27 @@ local handle_combination = function (combo, spec) end end - for j = 1, #def do - local this = def [j] - if type (this) == "number" then - report ("both", 0, "load", - " *> [%d][%d]: import codepoint U+%.4X", - i, j, this) - pickchr (this) - elseif type (this) == "table" then - local lo, hi = unpack (this) - report ("both", 0, "load", - " *> [%d][%d]: import codepoint range U+%.4X--U+%.4X", - i, j, lo, hi) - for uc = lo, hi do pickchr (uc) end - else - report ("both", 0, "load", - " *> item no. %d of combination definition \z - %d not processable.", j, i) + if def == true then --> fallback; grab all currently unavailable + for uc, _chr in next, src do pickchr (uc, true) end + else --> grab only defined range + for j = 1, #def do + local this = def [j] + if type (this) == "number" then + report ("both", 0, "load", + " *> [%d][%d]: import codepoint U+%.4X", + i, j, this) + pickchr (this) + elseif type (this) == "table" then + local lo, hi = unpack (this) + report ("both", 0, "load", + " *> [%d][%d]: import codepoint range U+%.4X--U+%.4X", + i, j, lo, hi) + for uc = lo, hi do pickchr (uc) end + else + report ("both", 0, "load", + " *> item no. %d of combination definition \z + %d not processable.", j, i) + end end end report ("both", 0, "load", diff --git a/src/luaotfload-loaders.lua b/src/luaotfload-loaders.lua index 80ce41a..fb01821 100644 --- a/src/luaotfload-loaders.lua +++ b/src/luaotfload-loaders.lua @@ -123,6 +123,7 @@ do logreport ("both", 0, "loaders", " > name %q", result.name or "<nil>") logreport ("both", 0, "loaders", " > fontname %q", result.fontname or "<nil>") logreport ("both", 0, "loaders", " > fullname %q", result.fullname or "<nil>") + logreport ("both", 0, "loaders", " > type %s", result.type or "<nil>") return result end end diff --git a/src/luaotfload-parsers.lua b/src/luaotfload-parsers.lua index 71e539d..b190c2c 100644 --- a/src/luaotfload-parsers.lua +++ b/src/luaotfload-parsers.lua @@ -591,11 +591,12 @@ local parenthesized = function (p) return P"(" * ws * p * ws * P")" end local comboidxpat = Cg(combouint, "idx") local comboidpat = Cg(combouint, "id" ) -local combocharspat = comboidpat * combodefsep * Cg(Ct(combochars^1), "chars") +local combocharspat = Cg(P"fallback" * Cc(true) + Ct(combochars^1), "chars") +local comboidcharspat = comboidpat * combodefsep * combocharspat -local comboidx = parenthesized (comboidxpat ) + comboidxpat -local comboid = parenthesized (comboidpat ) + comboidpat -local comboidchars = parenthesized (combocharspat) + combocharspat +local comboidx = parenthesized (comboidxpat ) + comboidxpat +local comboid = parenthesized (comboidpat ) + comboidpat +local comboidchars = parenthesized (comboidcharspat) + comboidcharspat local combodef1 = Ct(comboidx * combomapsep * comboid) --> no chars local combodef = Ct(comboidx * combomapsep * comboidchars) |