From db1581f06b8492b45384edf47db8876d331c4801 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Mon, 19 Dec 2011 20:19:51 +0200 Subject: Attempt to restore tlig and co --- luaotfload.dtx | 2 + otfl-font-otc.lua | 334 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 336 insertions(+) create mode 100644 otfl-font-otc.lua diff --git a/luaotfload.dtx b/luaotfload.dtx index ab8949c..d38ccd0 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -425,6 +425,7 @@ and the derived files % \item |font-map.lua| % \item |font-ota.lua| % \item |font-otb.lua| +% \item |font-otc.lua| % \item |font-otf.lua| % \item |font-oti.lua| % \item |font-otn.lua| @@ -580,6 +581,7 @@ require('otfl-font-otb.lua') require('otfl-node-inj.lua') require('otfl-font-otn.lua') require('otfl-font-ota.lua') +require('otfl-font-otc.lua') require('otfl-fonts-lua.lua') require('otfl-font-def.lua') require('otfl-font-ltx.lua') diff --git a/otfl-font-otc.lua b/otfl-font-otc.lua new file mode 100644 index 0000000..ae463e7 --- /dev/null +++ b/otfl-font-otc.lua @@ -0,0 +1,334 @@ +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 lpegmatch = lpeg.match + +-- 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 report_otf = logs.reporter("fonts","otf loading") + +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 +-- in the table using the original structure, we now have to operate on +-- the mkiv representation. And as the fontloader interface is modelled +-- after fontforge we cannot change that one too much either. + +local types = { + substitution = "gsub_single", + ligature = "gsub_ligature", + alternate = "gsub_alternate", +} + +setmetatableindex(types, function(t,k) t[k] = k return k end) -- "key" + +local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } +local noflags = { } + +local function addfeature(data,feature,specifications) + local descriptions = data.descriptions + local resources = data.resources + local lookups = resources.lookups + local gsubfeatures = resources.features.gsub + 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 + local skip = 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 valid = specification.valid + if not valid or valid(data,specification,feature) then + local initialize = specification.initialize + if initialize then + -- when false is returned we initialize only once + specification.initialize = initialize(specification) and initialize or nil + end + 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 + local unicode = tonumber(code) or unicodes[code] + local description = descriptions[unicode] + if description then + local slookups = description.slookups + if type(ligature) == "string" then + ligature = { lpegmatch(splitter,ligature) } + end + local present = true + for i=1,#ligature do + if not descriptions[ligature[i]] then + present = false + break + end + end + if present then + if slookups then + slookups[full] = ligature + else + description.slookups = { [full] = ligature } + end + done, added = done + 1, true + else + skip = skip + 1 + end + end + end + elseif featuretype == "gsub_single" then + lookuptypes[full] = "substitution" + for code, replacement in next, list do + local unicode = tonumber(code) or unicodes[code] + local description = descriptions[unicode] + if description then + local slookups = description.slookups + replacement = tonumber(replacement) or unicodes[replacement] + if descriptions[replacement] then + if slookups then + slookups[full] = replacement + else + description.slookups = { [full] = replacement } + end + done, added = done + 1, true + end + end + end + end + 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 + 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 language, value in next, languages do + kk[language] = value + end + end + end + end + end + if trace_loading then + report_otf("enhance: registering feature '%s', %s glyphs affected, %s glyphs skipped",feature,done,skip) + 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",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, + 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, + data = trep, + flags = noflags, +} + +otf.addfeature("trep",trep_specification) + +registerotffeature { + name = 'trep', + description = 'tex replacements', +} + +-- tcom + +if characters.combined then + + local tcom = { } + + local function initialize() + characters.initialize() + for first, seconds in next, characters.combined do + for second, combination in next, seconds do + tcom[combination] = { first, second } + end + end + -- return false + end + + local tcom_specification = { + type = "ligature", + features = everywhere, + data = tcom, + flags = noflags, + initialize = initialize, + } + + otf.addfeature("tcom",tcom_specification) + + registerotffeature { + name = 'tcom', + description = 'tex combinations', + } + +end + +-- 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 function valid(data) + local features = data.resources.features + if features then + for k, v in next, features do + for k, v in next, v do + if v.arab then + return true + end + end + end + end +end + +local anum_specification = { + { + type = "substitution", + features = { arab = { URD = true, dflt = true } }, + data = anum_arabic, + flags = noflags, -- { }, + valid = valid, + }, + { + type = "substitution", + features = { arab = { URD = true } }, + data = anum_persian, + flags = noflags, -- { }, + valid = valid, + }, +} + +otf.addfeature("anum",anum_specification) -- todo: only when there is already an arab script feature + +registerotffeature { + name = 'anum', + description = 'arabic digits', +} -- cgit v1.2.3