diff options
Diffstat (limited to 'tex/context/base/font-otc.lua')
-rw-r--r-- | tex/context/base/font-otc.lua | 304 |
1 files changed, 169 insertions, 135 deletions
diff --git a/tex/context/base/font-otc.lua b/tex/context/base/font-otc.lua index 5fdcf203b..1b4983ce0 100644 --- a/tex/context/base/font-otc.lua +++ b/tex/context/base/font-otc.lua @@ -19,6 +19,7 @@ local fonts = fonts local otf = fonts.handlers.otf local otffeatures = fonts.constructors.newfeatures("otf") local registerotffeature = otffeatures.register +local setmetatableindex = table.setmetatableindex -- In the userdata interface we can not longer tweak the loaded font as -- conveniently as before. For instance, instead of pushing extra data in @@ -26,118 +27,49 @@ local registerotffeature = otffeatures.register -- the mkiv representation. And as the fontloader interface is modelled -- after fontforge we cannot change that one too much either. -local extra_lists = { - tlig = { - { - endash = "hyphen hyphen", - emdash = "hyphen hyphen hyphen", - -- quotedblleft = "quoteleft quoteleft", - -- quotedblright = "quoteright quoteright", - -- quotedblleft = "grave grave", - -- quotedblright = "quotesingle quotesingle", - -- quotedblbase = "comma comma", - }, - }, - trep = { - { - -- [0x0022] = 0x201D, - [0x0027] = 0x2019, - -- [0x0060] = 0x2018, - }, - }, - anum = { - { -- arabic - [0x0030] = 0x0660, - [0x0031] = 0x0661, - [0x0032] = 0x0662, - [0x0033] = 0x0663, - [0x0034] = 0x0664, - [0x0035] = 0x0665, - [0x0036] = 0x0666, - [0x0037] = 0x0667, - [0x0038] = 0x0668, - [0x0039] = 0x0669, - }, - { -- persian - [0x0030] = 0x06F0, - [0x0031] = 0x06F1, - [0x0032] = 0x06F2, - [0x0033] = 0x06F3, - [0x0034] = 0x06F4, - [0x0035] = 0x06F5, - [0x0036] = 0x06F6, - [0x0037] = 0x06F7, - [0x0038] = 0x06F8, - [0x0039] = 0x06F9, - }, - }, +local types = { + substitution = "gsub_single", + ligature = "gsub_ligature", + alternate = "gsub_alternate", } -local extra_features = { -- maybe just 1..n so that we prescribe order - tlig = { - { - features = { ["*"] = { ["*"] = true } }, - name = "ctx_tlig_1", - subtables = { "ctx_tlig_1_s" }, - type = "gsub_ligature", - flags = { }, - }, - }, - trep = { - { - features = { ["*"] = { ["*"] = true } }, - name = "ctx_trep_1", - subtables = { "ctx_trep_1_s" }, - type = "gsub_single", - flags = { }, - }, - }, - anum = { - { - features = { arab = { URD = true, dflt = true } }, - name = "ctx_anum_1", - subtables = { "ctx_anum_1_s" }, - type = "gsub_single", - flags = { }, - }, - { - features = { arab = { URD = true } }, - name = "ctx_anum_2", - subtables = { "ctx_anum_2_s" }, - type = "gsub_single", - flags = { }, - }, - }, -} +setmetatableindex(types, function(t,k) t[k] = k return k end) -- "key" -otf.extrafeatures = extra_features -otf.extralists = extra_lists +local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } +local noflags = { } -local function enhancedata(data,filename,raw) +local function addfeature(data,feature,specifications) local descriptions = data.descriptions local resources = data.resources local lookups = resources.lookups local gsubfeatures = resources.features.gsub - local sequences = resources.sequences - local fontfeatures = resources.features - local unicodes = resources.unicodes - local lookuptypes = resources.lookuptypes - local splitter = lpeg.splitter(" ",unicodes) - for feature, specifications in next, extra_features do - if gsub and gsub[feature] then - -- already present - else - local done = 0 - for s=1,#specifications do - local specification = specifications[s] - local askedfeatures = specification.features - local subtables = specification.subtables - local featurename = specification.name - local featuretype = specification.type - local featureflags = specification.flags - local full = subtables[1] - local list = extra_lists[feature][s] - local added = false + if gsubfeatures and gsubfeatures[feature] then + -- already present + else + local sequences = resources.sequences + local fontfeatures = resources.features + local unicodes = resources.unicodes + local lookuptypes = resources.lookuptypes + local splitter = lpeg.splitter(" ",unicodes) + local done = 0 + if not specifications[1] then + -- so we accept a one entry specification + specifications = { specifications } + end + -- subtables are tables themselves but we also accept flattened singular subtables + for s=1,#specifications do + local specification = specifications[s] + local askedfeatures = specification.features or everywhere + local subtables = specification.subtables or { specification.data } or { } + local featuretype = types[specification.type or "substitution"] + local featureflags = specification.flags or noflags + local added = false + local featurename = format("ctx_%s_%s",feature,s) + local st = { } + for t=1,#subtables do + local list = subtables[t] + local full = format("%s_%s",featurename,t) + st[t] = full if featuretype == "gsub_ligature" then lookuptypes[full] = "ligature" for code, ligature in next, list do @@ -173,58 +105,160 @@ local function enhancedata(data,filename,raw) end end end - if added then - sequences[#sequences+1] = { - chain = 0, - features = { [feature] = askedfeatures }, - flags = featureflags, - name = featurename, - subtables = subtables, - type = featuretype, - } - -- register in metadata (merge as there can be a few) - if not gsubfeatures then - gsubfeatures = { } - fontfeatures.gsub = gsubfeatures + end + if added then + -- script = { lang1, lang2, lang3 } or script = { lang1 = true, ... } + for k, v in next, askedfeatures do + if v[1] then + askedfeatures[k] = table.tohash(v) end - local k = gsubfeatures[feature] - if not k then - k = { } - gsubfeatures[feature] = k + end + sequences[#sequences+1] = { + chain = 0, + features = { [feature] = askedfeatures }, + flags = featureflags, + name = featurename, + subtables = st, + type = featuretype, + } + -- register in metadata (merge as there can be a few) + if not gsubfeatures then + gsubfeatures = { } + fontfeatures.gsub = gsubfeatures + end + local k = gsubfeatures[feature] + if not k then + k = { } + gsubfeatures[feature] = k + end + for script, languages in next, askedfeatures do + local kk = k[script] + if not kk then + kk = { } + k[script] = kk end - for script, languages in next, askedfeatures do - local kk = k[script] - if not kk then - kk = { } - k[script] = kk - end - for language, value in next, languages do - kk[language] = value - end + for language, value in next, languages do + kk[language] = value end end end - if done > 0 and trace_loading then - report_otf("enhance: registering %s feature (%s glyphs affected)",feature,done) - end end + if done > 0 and trace_loading then + report_otf("enhance: registering %s feature (%s glyphs affected)",feature,done) + end + end +end + +otf.enhancers.addfeature = addfeature + +local extrafeatures = { } + +function otf.addfeature(name,specification) + extrafeatures[name] = specification +end + +local function enhance(data,filename,raw) + for feature, specification in next, extrafeatures do + addfeature(data,feature,specification) end end -otf.enhancers.register("check extra features",enhancedata) +otf.enhancers.register("check extra features",enhance) + +-- tlig -- + +local tlig = { + endash = "hyphen hyphen", + emdash = "hyphen hyphen hyphen", + -- quotedblleft = "quoteleft quoteleft", + -- quotedblright = "quoteright quoteright", + -- quotedblleft = "grave grave", + -- quotedblright = "quotesingle quotesingle", + -- quotedblbase = "comma comma", +} + +local tlig_specification = { + type = "ligature", + features = everywhere, -- { ["*"] = { ["*"] = true } }, + data = tlig, + flags = noflags, -- { }, +} + +otf.addfeature("tlig",tlig_specification) registerotffeature { name = 'tlig', description = 'tex ligatures', } +-- trep + +local trep = { + -- [0x0022] = 0x201D, + [0x0027] = 0x2019, + -- [0x0060] = 0x2018, +} + +local trep_specification = { + type = "substitution", + features = everywhere, -- { ["*"] = { ["*"] = true } }, + data = trep, + flags = noflags, -- { }, +} + +otf.addfeature("trep",trep_specification) + registerotffeature { name = 'trep', description = 'tex replacements', } +-- anum + +local anum_arabic = { + [0x0030] = 0x0660, + [0x0031] = 0x0661, + [0x0032] = 0x0662, + [0x0033] = 0x0663, + [0x0034] = 0x0664, + [0x0035] = 0x0665, + [0x0036] = 0x0666, + [0x0037] = 0x0667, + [0x0038] = 0x0668, + [0x0039] = 0x0669, +} + +local anum_persian = { + [0x0030] = 0x06F0, + [0x0031] = 0x06F1, + [0x0032] = 0x06F2, + [0x0033] = 0x06F3, + [0x0034] = 0x06F4, + [0x0035] = 0x06F5, + [0x0036] = 0x06F6, + [0x0037] = 0x06F7, + [0x0038] = 0x06F8, + [0x0039] = 0x06F9, +} + +local anum_specification = { + { + type = "substitution", + features = { arab = { URD = true, dflt = true } }, + data = anum_arabic, + flags = noflags, -- { }, + }, + { + type = "substitution", + features = { arab = { URD = true } }, + data = anum_persian, + flags = noflags, -- { }, + }, +} + +otf.addfeature("anum",anum_specification) + registerotffeature { name = 'anum', description = 'arabic digits', } - |