summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2016-02-16 08:23:41 +0100
committerPhilipp Gesang <phg@phi-gamma.net>2016-02-16 08:23:41 +0100
commitde3abd3209745257c1fbb7bf08be6b189d5e3cdd (patch)
treeb25832b0d6789b412701f91802719696c471f30f
parent0a1b9b746b5ce4cd740af8948f083685879c4eb9 (diff)
downloadluaotfload-de3abd3209745257c1fbb7bf08be6b189d5e3cdd.tar.gz
[features] handle combination definitions
-rw-r--r--src/luaotfload-features.lua113
1 files changed, 106 insertions, 7 deletions
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 ]]