if not modules then modules = { } end modules ['font-otc'] = { version = 1.001, comment = "companion to font-otf.lua (context)", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } local format, insert = string.format, table.insert local type, next = type, next local ctxcatcodes = tex.ctxcatcodes -- we assume that the other otf stuff is loaded already local trace_loading = false trackers.register("otf.loading", function(v) trace_loading = v end) local otf = fonts.otf local tfm = fonts.tfm -- instead of "script = "DFLT", langs = { 'dflt' }" we now use wildcards (we used to -- have always); some day we can write a "force always when true" trick for other -- features as well 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", exclamdown = "exclam grave", questiondown = "question grave", guillemotleft = "less less", guillemotright= "greater greater", }, }, 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 extra_features = { -- maybe just 1..n so that we prescribe order tlig = { { features = { { scripts = { { script = "*", langs = { "*" }, } }, tag = "tlig", comment = "added bij mkiv" }, }, name = "ctx_tlig_1", subtables = { { name = "ctx_tlig_1_s" } }, type = "gsub_ligature", flags = { }, }, }, trep = { { features = { { scripts = { { script = "*", langs = { "*" }, } }, tag = "trep", comment = "added bij mkiv" }, }, name = "ctx_trep_1", subtables = { { name = "ctx_trep_1_s" } }, type = "gsub_single", flags = { }, }, }, anum = { { features = { { scripts = { { script = "arab", langs = { "dflt", "FAR" }, } }, tag = "anum", comment = "added bij mkiv" }, }, name = "ctx_anum_1", subtables = { { name = "ctx_anum_1_s" } }, type = "gsub_single", flags = { }, }, { features = { { scripts = { { script = "arab", langs = { "URD" }, } }, tag = "anum", comment = "added bij mkiv" }, }, name = "ctx_anum_2", subtables = { { name = "ctx_anum_2_s" } }, type = "gsub_single", flags = { }, }, }, } fonts.otf.enhancers["add some missing characters"] = function(data,filename) -- todo end fonts.otf.enhancers["enrich with features"] = function(data,filename) -- could be done elsewhere (true can be #) local used = { } for i=1,#otf.glists do local g = data[otf.glists[i]] if g then for i=1,#g do local f = g[i].features if f then for i=1,#f do local t = f[i].tag if t then used[t] = true end end end end end end -- local glyphs = data.glyphs local indices = data.map.map data.gsub = data.gsub or { } for kind, specifications in next, extra_features do if not used[kind] then local done = 0 for s=1,#specifications do local added = false local specification = specifications[s] local list = extra_lists[kind][s] local name = specification.name .. "_s" if specification.type == "gsub_ligature" then for unicode, index in next, indices do local glyph = glyphs[index] local ligature = list[glyph.name] if ligature then local o = glyph.lookups or { } -- o[name] = { "ligature", ligature, glyph.name } o[name] = { { ["type"] = "ligature", ["specification"] = { char = glyph.name, components = ligature, } } } glyph.lookups, done, added = o, done+1, true end end elseif specification.type == "gsub_single" then for unicode, index in next, indices do local glyph = glyphs[index] local r = list[unicode] if r then local replacement = indices[r] if replacement and glyphs[replacement] then local o = glyph.lookups or { } -- o[name] = { { "substitution", glyphs[replacement].name } } o[name] = { { ["type"] = "substitution", ["specification"] = { variant = glyphs[replacement].name, } } } glyph.lookups, done, added = o, done+1, true end end end end if added then insert(data.gsub,s,table.fastcopy(specification)) -- right order end end if done > 0 then if trace_loading then logs.report("load otf","enhance: registering %s feature (%s glyphs affected)",kind,done) end end end end end otf.tables.features['tlig'] = 'TeX Ligatures' otf.tables.features['trep'] = 'TeX Replacements' otf.tables.features['anum'] = 'Arabic Digits' otf.features.register_base_substitution('tlig') otf.features.register_base_substitution('trep') otf.features.register_base_substitution('anum') -- the functionality is defined elsewhere fonts.initializers.base.otf.equaldigits = fonts.initializers.common.equaldigits fonts.initializers.node.otf.equaldigits = fonts.initializers.common.equaldigits fonts.initializers.base.otf.lineheight = fonts.initializers.common.lineheight fonts.initializers.node.otf.lineheight = fonts.initializers.common.lineheight fonts.initializers.base.otf.compose = fonts.initializers.common.compose fonts.initializers.node.otf.compose = fonts.initializers.common.compose -- bonus function function otf.name_to_slot(name) -- todo: afm en tfm local tfmdata = fonts.ids[font.current()] if tfmdata and tfmdata.shared then local otfdata = tfmdata.shared.otfdata local unicode = otfdata.luatex.unicodes[name] if not unicode then return string.byte("?") -- nil elseif type(unicode) == "number" then return unicode else return unicode[1] end end return nil end function otf.char(n) -- todo: afm en tfm if type(n) == "string" then n = otf.name_to_slot(n) end if n then tex.sprint(ctxcatcodes,format("\\char%s ",n)) end end