From 3447815896954281938500d49bedef715078a140 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Fri, 19 Feb 2016 22:41:23 +0100 Subject: [features,parsers] implement font fallbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/luaotfload-features.lua | 56 ++++++++++++++++++++++++++++----------------- src/luaotfload-loaders.lua | 1 + src/luaotfload-parsers.lua | 9 ++++---- 3 files changed, 41 insertions(+), 25 deletions(-) (limited to 'src') 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 "") logreport ("both", 0, "loaders", " > fontname %q", result.fontname or "") logreport ("both", 0, "loaders", " > fullname %q", result.fullname or "") + logreport ("both", 0, "loaders", " > type %s", result.type or "") 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) -- cgit v1.2.3