summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/font-otb.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/font-otb.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/font-otb.lua228
1 files changed, 115 insertions, 113 deletions
diff --git a/Master/texmf-dist/tex/context/base/font-otb.lua b/Master/texmf-dist/tex/context/base/font-otb.lua
index a4606d31951..a3d347737c8 100644
--- a/Master/texmf-dist/tex/context/base/font-otb.lua
+++ b/Master/texmf-dist/tex/context/base/font-otb.lua
@@ -1,6 +1,6 @@
if not modules then modules = { } end modules ['font-otb'] = {
version = 1.001,
- comment = "companion to font-ini.tex",
+ comment = "companion to font-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
@@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['font-otb'] = {
local concat = table.concat
local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
local type, next, tonumber, tostring = type, next, tonumber, tostring
+local lpegmatch = lpeg.match
local otf = fonts.otf
local tfm = fonts.tfm
@@ -69,7 +70,7 @@ local function resolve_ligatures(tfmdata,ligatures,kind)
for k,v in next, ligatures do
local lig = v[1]
if not done[lig] then
- local ligs = split_at_space:match(lig)
+ local ligs = lpegmatch(split_at_space,lig)
if #ligs == 2 then
local uc = v[2]
local c, f, s = characters[uc], ligs[1], ligs[2]
@@ -133,43 +134,12 @@ local function resolve_ligatures(tfmdata,ligatures,kind)
end
end
-local function collect_lookups(otfdata,kind,script,language)
- -- maybe store this in the font
- local sequences = otfdata.luatex.sequences
- if sequences then
- local featuremap, featurelist = { }, { }
- for s=1,#sequences do
- local sequence = sequences[s]
- local features = sequence.features
- features = features and features[kind]
- features = features and (features[script] or features[default] or features[wildcard])
- features = features and (features[language] or features[default] or features[wildcard])
- if features then
- local subtables = sequence.subtables
- if subtables then
- for s=1,#subtables do
- local ss = subtables[s]
- if not featuremap[s] then
- featuremap[ss] = true
- featurelist[#featurelist+1] = ss
- end
- end
- end
- end
- end
- if #featurelist > 0 then
- return featuremap, featurelist
- end
- end
- return nil, nil
-end
-
local splitter = lpeg.splitat(" ")
function prepare_base_substitutions(tfmdata,kind,value) -- we can share some code with the node features
if value then
local otfdata = tfmdata.shared.otfdata
- local validlookups, lookuplist = collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language)
+ local validlookups, lookuplist = otf.collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language)
if validlookups then
local ligatures = { }
local unicodes = tfmdata.unicodes -- names to unicodes
@@ -177,9 +147,84 @@ function prepare_base_substitutions(tfmdata,kind,value) -- we can share some cod
local characters = tfmdata.characters
local descriptions = tfmdata.descriptions
local changed = tfmdata.changed
+ --
+ local actions = {
+ substitution = function(p,lookup,k,glyph,unicode)
+ local pv = p[2] -- p.variant
+ if pv then
+ local upv = unicodes[pv]
+ if upv then
+ if type(upv) == "table" then
+ upv = upv[1]
+ end
+ if characters[upv] then
+ if trace_baseinit and trace_singles then
+ logs.report("define otf","%s: base substitution %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upv))
+ end
+ changed[k] = upv
+ end
+ end
+ end
+ end,
+ alternate = function(p,lookup,k,glyph,unicode)
+ local pc = p[2] -- p.components
+ if pc then
+ -- a bit optimized ugliness
+ if value == 1 then
+ pc = lpegmatch(splitter,pc)
+ elseif value == 2 then
+ local a, b = lpegmatch(splitter,pc)
+ pc = b or a
+ else
+ pc = { lpegmatch(splitter,pc) }
+ pc = pc[value] or pc[#pc]
+ end
+ if pc then
+ local upc = unicodes[pc]
+ if upc then
+ if type(upc) == "table" then
+ upc = upc[1]
+ end
+ if characters[upc] then
+ if trace_baseinit and trace_alternatives then
+ logs.report("define otf","%s: base alternate %s %s => %s",cref(kind,lookup),tostring(value),gref(descriptions,k),gref(descriptions,upc))
+ end
+ changed[k] = upc
+ end
+ end
+ end
+ end
+ end,
+ ligature = function(p,lookup,k,glyph,unicode)
+ local pc = p[2]
+ if pc then
+ if trace_baseinit and trace_ligatures then
+ local upc = { lpegmatch(splitter,pc) }
+ for i=1,#upc do upc[i] = unicodes[upc[i]] end
+ -- we assume that it's no table
+ logs.report("define otf","%s: base ligature %s => %s",cref(kind,lookup),gref(descriptions,upc),gref(descriptions,k))
+ end
+ ligatures[#ligatures+1] = { pc, k }
+ end
+ end,
+ }
+ --
for k,c in next, characters do
local glyph = descriptions[k]
- local lookups = glyph.lookups
+ local lookups = glyph.slookups
+ if lookups then
+ for l=1,#lookuplist do
+ local lookup = lookuplist[l]
+ local p = lookups[lookup]
+ if p then
+ local a = actions[p[1]]
+ if a then
+ a(p,lookup,k,glyph,unicode)
+ end
+ end
+ end
+ end
+ local lookups = glyph.mlookups
if lookups then
for l=1,#lookuplist do
local lookup = lookuplist[l]
@@ -187,62 +232,9 @@ function prepare_base_substitutions(tfmdata,kind,value) -- we can share some cod
if ps then
for i=1,#ps do
local p = ps[i]
- local t = p[1]
- if t == 'substitution' then
- local pv = p[2] -- p.variant
- if pv then
- local upv = unicodes[pv]
- if upv then
- if type(upv) == "table" then
- upv = upv[1]
- end
- if characters[upv] then
- if trace_baseinit and trace_singles then
- logs.report("define otf","%s: base substitution %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upv))
- end
- changed[k] = upv
- end
- end
- end
- elseif t == 'alternate' then
- local pc = p[2] -- p.components
- if pc then
- -- a bit optimized ugliness
- if value == 1 then
- pc = splitter:match(pc)
- elseif value == 2 then
- local a, b = splitter:match(pc)
- pc = b or a
- else
- pc = { splitter:match(pc) }
- pc = pc[value] or pc[#pc]
- end
- if pc then
- local upc = unicodes[pc]
- if upc then
- if type(upc) == "table" then
- upc = upc[1]
- end
- if characters[upc] then
- if trace_baseinit and trace_alternatives then
- logs.report("define otf","%s: base alternate %s => %s",cref(kind,lookup),gref(descriptions,k),gref(descriptions,upc))
- end
- changed[k] = upc
- end
- end
- end
- end
- elseif t == 'ligature' and not changed[k] then
- local pc = p[2]
- if pc then
- if trace_baseinit and trace_ligatures then
- local upc = { splitter:match(pc) }
- for i=1,#upc do upc[i] = unicodes[upc[i]] end
- -- we assume that it's no table
- logs.report("define otf","%s: base ligature %s => %s",cref(kind,lookup),gref(descriptions,upc),gref(descriptions,k))
- end
- ligatures[#ligatures+1] = { pc, k }
- end
+ local a = actions[p[1]]
+ if a then
+ a(p,lookup,k,glyph,unicode)
end
end
end
@@ -259,37 +251,46 @@ end
local function prepare_base_kerns(tfmdata,kind,value) -- todo what kind of kerns, currently all
if value then
local otfdata = tfmdata.shared.otfdata
- local validlookups, lookuplist = collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language)
+ local validlookups, lookuplist = otf.collect_lookups(otfdata,kind,tfmdata.script,tfmdata.language)
if validlookups then
local unicodes = tfmdata.unicodes -- names to unicodes
local indices = tfmdata.indices
local characters = tfmdata.characters
local descriptions = tfmdata.descriptions
+ local sharedkerns = { }
for u, chr in next, characters do
local d = descriptions[u]
if d then
- local dk = d.mykerns
+ local dk = d.mykerns -- shared
if dk then
- local t, done = chr.kerns or { }, false
- for l=1,#lookuplist do
- local lookup = lookuplist[l]
- local kerns = dk[lookup]
- if kerns then
- for k, v in next, kerns do
- if v ~= 0 and not t[k] then -- maybe no 0 test here
- t[k], done = v, true
- if trace_baseinit and trace_kerns then
- logs.report("define otf","%s: base kern %s + %s => %s",cref(kind,lookup),gref(descriptions,u),gref(descriptions,k),v)
+ local s = sharedkerns[dk]
+ if s == false then
+ -- skip
+ elseif s then
+ chr.kerns = s
+ else
+ local t, done = chr.kerns or { }, false
+ for l=1,#lookuplist do
+ local lookup = lookuplist[l]
+ local kerns = dk[lookup]
+ if kerns then
+ for k, v in next, kerns do
+ if v ~= 0 and not t[k] then -- maybe no 0 test here
+ t[k], done = v, true
+ if trace_baseinit and trace_kerns then
+ logs.report("define otf","%s: base kern %s + %s => %s",cref(kind,lookup),gref(descriptions,u),gref(descriptions,k),v)
+ end
end
end
end
end
+ if done then
+ sharedkerns[dk] = t
+ chr.kerns = t -- no empty assignments
+ else
+ sharedkerns[dk] = false
+ end
end
- if done then
- chr.kerns = t -- no empty assignments
- end
- -- elseif d.kerns then
- -- logs.report("define otf","%s: invalid mykerns for %s",cref(kind),gref(descriptions,u))
end
end
end
@@ -304,12 +305,13 @@ end
-- to do complete mixed runs and not run featurewise (as we did before).
local supported_gsub = {
- 'liga','dlig','rlig','hlig',
- 'pnum','onum','tnum','lnum',
+ 'liga', 'dlig', 'rlig', 'hlig',
+ 'pnum', 'onum', 'tnum', 'lnum',
'zero',
- 'smcp','cpsp','c2sc','ornm','aalt',
- 'hwid','fwid',
- 'ssty', -- math
+ 'smcp', 'cpsp', 'c2sc', 'ornm', 'aalt',
+ 'hwid', 'fwid',
+ 'ssty', 'rtlm', -- math
+-- 'tlig', 'trep',
}
local supported_gpos = {