summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2016-02-19 22:41:23 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2016-02-19 22:48:02 +0100
commit3447815896954281938500d49bedef715078a140 (patch)
treed41348716e437e223fcf30ae636c9bc32e645639
parent9e04cce348b4de350b2e0612698c81311e6e6e9d (diff)
downloadluaotfload-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.lua56
-rw-r--r--src/luaotfload-loaders.lua1
-rw-r--r--src/luaotfload-parsers.lua9
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)