diff options
| author | Khaled Hosny <khaledhosny@eglug.org> | 2011-12-19 20:19:51 +0200 | 
|---|---|---|
| committer | Khaled Hosny <khaledhosny@eglug.org> | 2011-12-19 20:19:51 +0200 | 
| commit | db1581f06b8492b45384edf47db8876d331c4801 (patch) | |
| tree | 1e89c9bf7996612778eea7ab36dc5f1c16760ce9 | |
| parent | 7b028b4346551f61450d42da5a52cdf85407674c (diff) | |
| download | luaotfload-db1581f06b8492b45384edf47db8876d331c4801.tar.gz | |
Attempt to restore tlig and co
| -rw-r--r-- | luaotfload.dtx | 2 | ||||
| -rw-r--r-- | otfl-font-otc.lua | 334 | 
2 files changed, 336 insertions, 0 deletions
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', +}  | 
