diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/font-otc.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/font-otc.lua | 322 |
1 files changed, 300 insertions, 22 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/font-otc.lua b/Master/texmf-dist/tex/context/base/mkiv/font-otc.lua index a774a81c2c9..2bad62d60f0 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/font-otc.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/font-otc.lua @@ -6,10 +6,11 @@ if not modules then modules = { } end modules ['font-otc'] = { license = "see context related readme files" } -local insert, sortedkeys, sortedhash, tohash = table.insert, table.sortedkeys, table.sortedhash, table.tohash -local type, next, tonumber = type, next, tonumber +local format, insert, sortedkeys, tohash = string.format, table.insert, table.sortedkeys, table.tohash +local type, next = type, next local lpegmatch = lpeg.match -local utfbyte, utflen = utf.byte, utf.len +local utfbyte, utflen, utfsplit = utf.byte, utf.len, utf.split +local match = string.match local sortedhash = table.sortedhash -- we assume that the other otf stuff is loaded already @@ -174,10 +175,6 @@ local function addfeature(data,feature,specifications) return end - local p = lpeg.P("P") - * (lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end) - * lpeg.P(-1) - local function tounicode(code) if not code then return @@ -187,7 +184,6 @@ local function addfeature(data,feature,specifications) end local u = unicodes[code] if u then - -- unicodes[code] = u return u end if utflen(code) == 1 then @@ -196,19 +192,10 @@ local function addfeature(data,feature,specifications) return u end end - local u = lpegmatch(p,code) - if u then - -- unicodes[code] = u - return u - end if not aglunicodes then aglunicodes = fonts.encodings.agl.unicodes -- delayed end - local u = aglunicodes[code] - if u then - -- unicodes[code] = u - return u - end + return aglunicodes[code] end local coverup = otf.coverup @@ -278,8 +265,7 @@ local function addfeature(data,feature,specifications) if not nocheck and not description then skip = skip + 1 elseif type(replacement) == "table" then - local r = { } - local n = 0 + local r, n = { }, 0 for i=1,#replacement do local u = tounicode(replacement[i]) if nocheck or descriptions[u] then @@ -481,8 +467,6 @@ local function addfeature(data,feature,specifications) if not subtype then subtype = lookup.type end - elseif v == 0 then - lookups[k] = { { type = "gsub_remove" } } else lookups[k] = false -- { false } -- new end @@ -829,6 +813,177 @@ otf.enhancers.enhance = enhance otf.enhancers.register("check extra features",enhance) +-- tlig -- + +local tlig = { -- we need numbers for some fonts so ... + -- endash = "hyphen hyphen", + -- emdash = "hyphen hyphen hyphen", + [0x2013] = { 0x002D, 0x002D }, + [0x2014] = { 0x002D, 0x002D, 0x002D }, + -- quotedblleft = "quoteleft quoteleft", + -- quotedblright = "quoteright quoteright", + -- quotedblleft = "grave grave", + -- quotedblright = "quotesingle quotesingle", + -- quotedblbase = "comma comma", +} + +local tlig_specification = { + type = "ligature", + features = everywhere, + data = tlig, + order = { "tlig" }, + flags = noflags, + prepend = true, +} + +otf.addfeature("tlig",tlig_specification) + +registerotffeature { + -- this makes it a known feature (in tables) + name = 'tlig', + description = 'tex ligatures', +} + +-- trep + +local trep = { + -- [0x0022] = 0x201D, + [0x0027] = 0x2019, + -- [0x0060] = 0x2018, +} + +local trep_specification = { + type = "substitution", + features = everywhere, + data = trep, + order = { "trep" }, + flags = noflags, + prepend = true, +} + +otf.addfeature("trep",trep_specification) + +registerotffeature { + -- this makes it a known feature (in tables) + name = 'trep', + description = 'tex replacements', +} + +-- -- tcom (obsolete, was already not set for a while) + +-- 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, +-- order = { "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 } }, + order = { "anum" }, + data = anum_arabic, + flags = noflags, -- { }, + valid = valid, + }, + { + type = "substitution", + features = { arab = { urd = true } }, + order = { "anum" }, + data = anum_persian, + flags = noflags, -- { }, + valid = valid, + }, +} + +otf.addfeature("anum",anum_specification) -- todo: only when there is already an arab script feature + +registerotffeature { + -- this makes it a known feature (in tables) + name = 'anum', + description = 'arabic digits', +} + +-- maybe: + +-- fonts.handlers.otf.addfeature("hangulfix",{ +-- type = "substitution", +-- features = { ["hang"] = { ["*"] = true } }, +-- data = { +-- [0x1160] = 0x119E, +-- }, +-- order = { "hangulfix" }, +-- flags = { }, +-- prepend = true, +-- }) + -- fonts.handlers.otf.features.register { -- name = 'hangulfix', -- description = 'fixes for hangul', @@ -873,3 +1028,126 @@ otf.enhancers.register("check extra features",enhance) -- a = { b = -500 }, -- } -- } + +-- This is a quick and dirty hack. + +local lookups = { } +local protect = { } +local revert = { } +local zwjchar = 0x200C +local zwj = { zwjchar } + +otf.addfeature { + name = "blockligatures", + type = "chainsubstitution", + nocheck = true, -- because there is no 0x200C in the font + prepend = true, -- make sure we do it early + future = true, -- avoid nilling due to no steps yet + lookups = { + { + type = "multiple", + data = lookups, + }, + }, + data = { + rules = protect, + } +} + +otf.addfeature { + name = "blockligatures", + type = "chainsubstitution", + nocheck = true, -- because there is no 0x200C in the font + append = true, -- this is done late + overload = false, -- we don't want to overload the previous definition + lookups = { + { + type = "ligature", + data = lookups, + }, + }, + data = { + rules = revert, + } +} + +registerotffeature { + name = 'blockligatures', + description = 'block certain ligatures', +} + +local settings_to_array = utilities.parsers and utilities.parsers.settings_to_array + or function(s) return string.split(s,",") end -- for generic + +local splitter = lpeg.splitat(":") + +local function blockligatures(str) + + local t = settings_to_array(str) + + for i=1,#t do + local ti = t[i] + local before, current, after = lpegmatch(splitter,ti) + if current and after then -- before is returned when no match + -- experimental joke + if before then + before = utfsplit(before) + for i=1,#before do + before[i] = { before[i] } + end + end + if current then + current = utfsplit(current) + end + if after then + after = utfsplit(after) + for i=1,#after do + after[i] = { after[i] } + end + end + else + before = nil + current = utfsplit(ti) + after = nil + end + if #current > 1 then + local one = current[1] + local two = current[2] + lookups[one] = { one, zwjchar } + local one = { one } + local two = { two } + local new = #protect + 1 + protect[new] = { + before = before, + current = { one, two }, + after = after, + lookups = { 1 }, -- not shared ! + } + revert[new] = { + -- before = before, + current = { one, zwj }, + -- after = { two, unpack(after) }, + after = { two }, + lookups = { 1 }, -- not shared ! + } + end + end +end + +-- blockligatures("\0\0") + +otf.helpers.blockligatures = blockligatures + +-- blockligatures("fi,ff") +-- blockligatures("fl") +-- blockligatures("u:fl:age") + +if context then + + interfaces.implement { + name = "blockligatures", + arguments = "string", + actions = blockligatures, + } + +end |