From de3abd3209745257c1fbb7bf08be6b189d5e3cdd Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 16 Feb 2016 08:23:41 +0100 Subject: [features] handle combination definitions --- src/luaotfload-features.lua | 113 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 7 deletions(-) (limited to 'src/luaotfload-features.lua') diff --git a/src/luaotfload-features.lua b/src/luaotfload-features.lua index 6df04b2..723fd54 100644 --- a/src/luaotfload-features.lua +++ b/src/luaotfload-features.lua @@ -19,6 +19,7 @@ local C = lpeg.C local table = table local tabletohash = table.tohash +local tablesort = table.sort local setmetatableindex = table.setmetatableindex local insert = table.insert @@ -28,6 +29,7 @@ local insert = table.insert local fonts = fonts local definers = fonts.definers local handlers = fonts.handlers +local fontidentifiers = fonts.hashes and fonts.hashes.identifiers local as_script, normalize @@ -65,6 +67,104 @@ local stringformat = string.format local stringis_empty = string.is_empty local mathceil = math.ceil +local cmp_by_idx = function (a, b) return a.idx < b.idx end + +local handle_combination = function (combo, spec) + if not combo [1] then + report ("both", 0, "load", "Empty font combination requested.") + return false + end + inspect(combo) + + if not fontidentifiers then + fontidentifiers = fonts.hashes and fonts.hashes.identifiers + end + + local chain = { } + local fontids = { } + local n = #combo + + tablesort (combo, cmp_by_idx) + + --- pass 1: skim combo and resolve fonts + report ("both", 0, "load", "Combining %d fonts.", n) + for i = 1, n do + local cur = combo [i] + local id = cur.id + local idx = cur.idx + 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)) + chain [#chain + 1] = { fnt, chars, idx = idx } + fontids [#fontids + 1] = id + else + report ("both", 0, "load", + " *> %.2d: font %d at rank %d unknown, skipping.", + n, id, idx) + --- TODO might instead attempt to define the font at this point + --- but that’d require some modifications to the syntax + end + end + + local nc = #chain + if nc == 0 then + report ("both", 0, "load", + " *> no valid font (of %d) in combination.", n) + return false + end + + local basefnt = chain [1] [1] + if nc == 1 then + report ("both", 0, "load", + " *> combination boils down to a single font (%s) \z + of %d initially specified; not pursuing this any \z + further.", basefnt.fullname, n) + return basefnt + end + + local basechar = basefnt.characters + local baseprop = basefnt.properties + baseprop.name = spec.name + baseprop.virtualized = true + baseprop.fonts = fontids + + for i = 2, nc do + local cur = chain [i] + local fnt = cur [1] + local def = cur [2] + local src = fnt.characters + local cnt = 0 + + local pickchr = function (uc) + local chr = src [uc] + if chr then + chr.commands = { "slot", i, uc } + basechar [uc] = chr + cnt = cnt + 1 + end + end + + for j = 1, #def do + local this = def [j] + if type (this) == "number" then + pickchr (this) + elseif type (this) == "table" then + for uc = this [1], this [2] do pickchr (uc) end + else + report ("both", 0, "load", + " *> item no. %d of combination definition \z + %d not processable.", j, i) + end + end + report ("both", 0, "load", + " *> font %d / %d: imported %d glyphs into combo.", + i, nc, cnt) + end + return basefnt +end ---[[ begin excerpt from font-ott.lua ]] @@ -1082,13 +1182,12 @@ local handle_request = function (specification) return specification end - local lookup, name = select_lookup(request) + local lookup, name = select_lookup (request) if lookup == "combo" then - report ("both", 0, "load", - "‘combo’ lookup not implemented at this stage.") - os.exit(-42) + return handle_combination (request.combo, specification) end - request.features = apply_default_features(request.features) + + request.features = apply_default_features(request.features) if name then specification.name = name @@ -1126,8 +1225,8 @@ if as_script == true then --- skip the remainder of the file return else local registersplit = definers.registersplit - registersplit (":", handle_request, "cryptic") - registersplit ("", handle_request, "more cryptic") -- catches \font\text=[names] + registersplit (":", handle_request, "common") + registersplit ("", handle_request, "xetex path style") -- catches \font\text=[names] end ---[[ end included font-ltx.lua ]] -- cgit v1.2.3