diff options
| -rw-r--r-- | filegraph.dot | 60 | ||||
| -rwxr-xr-x | fontdbutil.lua (renamed from mkluatexfontdb.lua) | 14 | ||||
| -rw-r--r-- | luaotfload-basics-gen.lua (renamed from otfl-basics-gen.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-basics-nod.lua (renamed from otfl-basics-nod.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-blacklist.cnf (renamed from otfl-blacklist.cnf) | 0 | ||||
| -rw-r--r-- | luaotfload-colors.lua (renamed from otfl-font-clr.lua) | 4 | ||||
| -rw-r--r-- | luaotfload-database.lua (renamed from otfl-font-nms.lua) | 6 | ||||
| -rw-r--r-- | luaotfload-features.lua | 575 | ||||
| -rw-r--r-- | luaotfload-fonts-cbk.lua (renamed from otfl-fonts-cbk.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-fonts-def.lua (renamed from otfl-fonts-def.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-fonts-enc.lua (renamed from otfl-fonts-enc.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-fonts-ext.lua (renamed from otfl-fonts-ext.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-fonts-lua.lua (renamed from otfl-fonts-lua.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-fonts-tfm.lua (renamed from otfl-fonts-tfm.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-lib-dir.lua (renamed from otfl-lib-dir.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-loaders.lua (renamed from otfl-font-pfb.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-merged.lua (renamed from otfl-fonts-merged.lua) | 0 | ||||
| -rw-r--r-- | luaotfload-override.lua (renamed from otfl-luat-ovr.lua) | 3 | ||||
| -rw-r--r-- | luaotfload.dtx | 652 | ||||
| -rw-r--r-- | luaotfload.lua | 457 | ||||
| -rw-r--r-- | otfl-features.lua | 110 | ||||
| -rw-r--r-- | otfl-font-ltx.lua | 205 | ||||
| -rw-r--r-- | otfl-font-otc.lua | 333 | ||||
| -rw-r--r-- | otfl-fonts.lua | 253 | ||||
| -rw-r--r-- | tests/lookups.tex | 14 | 
25 files changed, 951 insertions, 1735 deletions
| diff --git a/filegraph.dot b/filegraph.dot index f3ab2f2..9b79953 100644 --- a/filegraph.dot +++ b/filegraph.dot @@ -27,8 +27,11 @@ strict digraph luaotfload_files { //looks weird with circo ...  /* ····································································   * file structure   * ································································· */ -    luaotfload -> otfl_fonts -    otfl_fonts -> otfl_fonts_merged [label="merged"] +    luaotfload -> otfl_fonts_merged [label="merged"] +    luaotfload -> merged_lua_libs     [label="unmerged", style=solid] +    luaotfload -> merged_luatex_fonts [label="unmerged", style=solid] +    luaotfload -> merged_context_libs [label="unmerged", style=solid] +      luaotfload -> luaotfload_libs      luaotfload -> otfl_blacklist_cnf @@ -43,9 +46,6 @@ strict digraph luaotfload_files { //looks weird with circo ...                                                style=dotted,                                                lhead=cluster_merged] -    otfl_fonts -> merged_lua_libs     [label="unmerged", style=solid] -    otfl_fonts -> merged_luatex_fonts [label="unmerged", style=solid] -    otfl_fonts -> merged_context_libs [label="unmerged", style=solid]  /* ···································································· @@ -59,14 +59,16 @@ strict digraph luaotfload_files { //looks weird with circo ...                         color  = "#01012222",                         style  = "filled,rounded",                         penwidth=2] -    otfl_fonts        [label = "otfl-fonts.lua", -                       shape = rect, -                       width  = "3.2cm", -                       height = "1.2cm", -                       color  = "#01012222", -                       style  = "filled,rounded", -                       penwidth=2] -    otfl_fonts_merged [label = "otfl-fonts-merged.lua", +    /* +     *otfl_fonts        [label = "luaotfload-fonts.lua", +     *                   shape = rect, +     *                   width  = "3.2cm", +     *                   height = "1.2cm", +     *                   color  = "#01012222", +     *                   style  = "filled,rounded", +     *                   penwidth=2] +     */ +    otfl_fonts_merged [label = "luaotfload-merged.lua",                         shape = rect,                         width  = "3.2cm",                         height = "1.2cm", @@ -78,28 +80,6 @@ strict digraph luaotfload_files { //looks weird with circo ...   * luaotfload files   * ································································· */ -/* - *    subgraph cluster_luaotfload_libs { - *        style     = "filled,rounded"; - *        color     = "grey90:goldenrod4"; - *        gradientangle=0; - *        //nodesep   = "3.0"; - *        rank      = same; - *        label     = "Luaotfload"; - *        otfl_font_otc;  otfl_lib_dir;   otfl_luat_ovr; - *        otfl_font_pfb;  otfl_font_nms;  otfl_font_clr; - *        otfl_font_ltx;  otfl_features;  otfl_blacklist_cnf; - *    } - * - *    otfl_font_otc      [style=filled, color=white, shape=box, label="otfl-font-otc.lua"] - *    otfl_lib_dir       [style=filled, color=white, shape=box, label="otfl-lib-dir.lua"] - *    otfl_luat_ovr      [style=filled, color=white, shape=box, label="otfl-luat-ovr.lua"] - *    otfl_font_pfb      [style=filled, color=white, shape=box, label="otfl-font-pfb.lua"] - *    otfl_font_nms      [style=filled, color=white, shape=box, label="otfl-font-nms.lua"] - *    otfl_font_clr      [style=filled, color=white, shape=box, label="otfl-font-clr.lua"] - *    otfl_font_ltx      [style=filled, color=white, shape=box, label="otfl-font-ltx.lua"] - *    otfl_features      [style=filled, color=white, shape=box, label="otfl-features.lua"] - */      otfl_blacklist_cnf [style      = "filled,dashed",                          shape      = rect, @@ -107,7 +87,7 @@ strict digraph luaotfload_files { //looks weird with circo ...                          fillcolor  = "#01012222",                          color      = grey40,                          style      = "filled,dotted,rounded", -                        label      = "otfl-blacklist.cnf"] +                        label      = "luaotfload-blacklist.cnf"]      luaotfload_libs [          shape      = box, @@ -117,10 +97,10 @@ strict digraph luaotfload_files { //looks weird with circo ...          label      = <              <table cellborder="0" bgcolor="#FFFFFFAA">                  <th> <td colspan="2"> <font point-size="12" face="Iwona Italic">Luaotfload Libraries</font> </td> </th> -                <tr> <td>otfl-font-otc.lua</td> <td>otfl-lib-dir.lua</td>  </tr> -                <tr> <td>otfl-luat-ovr.lua</td> <td>otfl-font-pfb.lua</td> </tr> -                <tr> <td>otfl-font-nms.lua</td> <td>otfl-font-clr.lua</td> </tr> -                <tr> <td>otfl-font-ltx.lua</td> <td>otfl-features.lua</td> </tr> +                <tr> <td>luaotfload-font-otc.lua</td> <td>luaotfload-lib-dir.lua</td> </tr> +                <tr> <td>luaotfload-override.lua</td> <td>luaotfload-loaders.lua</td> </tr> +                <tr> <td>luaotfload-database.lua</td> <td>luaotfload-color.lua</td>   </tr> +                <tr> <td>luaotfload-features.lua</td> </tr>              </table>          >,      ] diff --git a/mkluatexfontdb.lua b/fontdbutil.lua index 96dcf60..31c7dfa 100755 --- a/mkluatexfontdb.lua +++ b/fontdbutil.lua @@ -9,10 +9,10 @@ luaotfload bundle, please see the luaotfload documentation for more info.  kpse.set_program_name"luatex" -local stringformat  = string.format -local texiowrite_nl = texio.write_nl -local stringfind    = string.find -local stringlower   = string.lower +local stringformat    = string.format +local texiowrite_nl   = texio.write_nl +local stringfind      = string.find +local stringlower     = string.lower  -- First we need to be able to load module (code copied from  -- luatexbase-loader.sty): @@ -73,9 +73,9 @@ config.lualibs.prefer_merged    = true  config.lualibs.load_extended    = false  require"lualibs" -require"otfl-basics-gen.lua" -require"otfl-luat-ovr.lua"  --- this populates the logs.* namespace -require"otfl-font-nms" +require"luaotfload-basics-gen.lua" +require"luaotfload-override.lua"  --- this populates the logs.* namespace +require"luaotfload-database"  require"alt_getopt"  local version = "2.2" -- same version number as luaotfload diff --git a/otfl-basics-gen.lua b/luaotfload-basics-gen.lua index 727086e..727086e 100644 --- a/otfl-basics-gen.lua +++ b/luaotfload-basics-gen.lua diff --git a/otfl-basics-nod.lua b/luaotfload-basics-nod.lua index 151d98a..151d98a 100644 --- a/otfl-basics-nod.lua +++ b/luaotfload-basics-nod.lua diff --git a/otfl-blacklist.cnf b/luaotfload-blacklist.cnf index 771649b..771649b 100644 --- a/otfl-blacklist.cnf +++ b/luaotfload-blacklist.cnf diff --git a/otfl-font-clr.lua b/luaotfload-colors.lua index 439fd7c..3d8bfab 100644 --- a/otfl-font-clr.lua +++ b/luaotfload-colors.lua @@ -1,6 +1,6 @@ -if not modules then modules = { } end modules ['font-clr'] = { +if not modules then modules = { } end modules ['luaotfload-colors'] = {      version   = 1.001, -    comment   = "companion to font-otf.lua (font color)", +    comment   = "companion to luaotfload.lua (font color)",      author    = "Khaled Hosny and Elie Roux",      copyright = "Luaotfload Development Team",      license   = "GPL" diff --git a/otfl-font-nms.lua b/luaotfload-database.lua index 35611a6..19b04db 100644 --- a/otfl-font-nms.lua +++ b/luaotfload-database.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['font-nms'] = { +if not modules then modules = { } end modules ['luaotfload-database'] = {      version   = 2.2,      comment   = "companion to luaotfload.lua",      author    = "Khaled Hosny and Elie Roux", @@ -66,7 +66,7 @@ local names          = fonts.names  names.version        = 2.2  names.data           = nil  names.path           = { -    basename = "otfl-names.lua", +    basename = "luaotfload-names.lua",      dir      = "",      path     = "",  } @@ -704,7 +704,7 @@ names.blacklist = { }  local function read_blacklist()      local files = { -        kpselookup("otfl-blacklist.cnf", {all=true, format="tex"}) +        kpselookup("luaotfload-blacklist.cnf", {all=true, format="tex"})      }      local blacklist = names.blacklist      local whitelist = { } diff --git a/luaotfload-features.lua b/luaotfload-features.lua new file mode 100644 index 0000000..0121ede --- /dev/null +++ b/luaotfload-features.lua @@ -0,0 +1,575 @@ +if not modules then modules = { } end modules ["features"] = { +    version   = 1.000, +    comment   = "companion to luaotfload.lua", +    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 + +---[[ begin included font-ltx.lua ]] +--- this appears to be based in part on luatex-fonts-def.lua + +local fonts = fonts + +-- A bit of tuning for definitions. + +fonts.constructors.namemode = "specification" -- somehow latex needs this (changed name!) => will change into an overload + +-- tricky: we sort of bypass the parser and directly feed all into +-- the sub parser + +function fonts.definers.getspecification(str) +    return "", str, "", ":", str +end + +local feature_list = { } + +local report = logs.names_report + +local stringlower      = string.lower +local stringsub        = string.sub +local stringgsub       = string.gsub +local stringfind       = string.find +local stringexplode    = string.explode +local stringis_empty   = string.is_empty + +local supported = { +    b    = "bold", +    i    = "italic", +    bi   = "bolditalic", +    aat  = false, +    icu  = false, +    gr   = false, +} + +--- this parses the optional flags after the slash +--- the original behavior is that multiple slashes +--- are valid but they might cancel prior settings +--- example: {name:Antykwa Torunska/I/B} -> bold + +local isstyle = function (request) +    request = stringlower(request) +    request = stringexplode(request, "/") + +    for _,v in next, request do +        local stylename = supported[v] +        if stylename then +            feature_list.style = stylename +        elseif stringfind(v, "^s=") then +            --- after all, we want everything after the second byte ... +            local val = stringsub(v, 3) +            feature_list.optsize = val +        elseif stylename == false then +            report("log", 0, +                "load font", "unsupported font option: %s", v) +        elseif not stringis_empty(v) then +            feature_list.style = stringgsub(v, "[^%a%d]", "") +        end +    end +end + +local defaults = { +    dflt = { +        "ccmp", "locl", "rlig", "liga", "clig", +        "kern", "mark", "mkmk", 'itlc', +    }, +    arab = { +        "ccmp", "locl", "isol", "fina", "fin2", +        "fin3", "medi", "med2", "init", "rlig", +        "calt", "liga", "cswh", "mset", "curs", +        "kern", "mark", "mkmk", +    }, +    deva = { +        "ccmp", "locl", "init", "nukt", "akhn", +        "rphf", "blwf", "half", "pstf", "vatu", +        "pres", "blws", "abvs", "psts", "haln", +        "calt", "blwm", "abvm", "dist", "kern", +        "mark", "mkmk", +    }, +    khmr = { +        "ccmp", "locl", "pref", "blwf", "abvf", +        "pstf", "pres", "blws", "abvs", "psts", +        "clig", "calt", "blwm", "abvm", "dist", +        "kern", "mark", "mkmk", +    }, +    thai = { +        "ccmp", "locl", "liga", "kern", "mark", +        "mkmk", +    }, +    hang = { +        "ccmp", "ljmo", "vjmo", "tjmo", +    }, +} + +defaults.beng = defaults.deva +defaults.guru = defaults.deva +defaults.gujr = defaults.deva +defaults.orya = defaults.deva +defaults.taml = defaults.deva +defaults.telu = defaults.deva +defaults.knda = defaults.deva +defaults.mlym = defaults.deva +defaults.sinh = defaults.deva + +defaults.syrc = defaults.arab +defaults.mong = defaults.arab +defaults.nko  = defaults.arab + +defaults.tibt = defaults.khmr + +defaults.lao  = defaults.thai + +local function set_default_features(script) +    local features +    local script = script or "dflt" +    report("log", 0, "load font", +        "auto-selecting default features for script: %s", +        script) +    if defaults[script] then +        features = defaults[script] +    else +        features = defaults["dflt"] +    end +    for _,v in next, features do +        if feature_list[v] ~= false then +            feature_list[v] = true +        end +    end +end + +local function issome ()    feature_list.lookup = 'name' end +local function isfile ()    feature_list.lookup = 'file' end +local function isname ()    feature_list.lookup = 'name' end +local function thename(s)   feature_list.name   = s end +local function issub  (v)   feature_list.sub    = v end +local function istrue (s)   feature_list[s]     = true end +local function isfalse(s)   feature_list[s]     = false end +local function iskey  (k,v) feature_list[k]     = v end + +local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C + +local spaces     = P(" ")^0 +--local namespec   = (1-S("/:("))^0 -- was: (1-S("/: ("))^0 +--[[phg-- this prevents matching of absolute paths as file names --]]-- +local namespec   = (1-S("/:("))^1 +local filespec   = (R("az", "AZ") * P(":"))^-1 * (1-S(":("))^1 +local stylespec  = spaces * P("/") * (((1-P(":"))^0)/isstyle) * spaces +local filename   = (P("file:")/isfile * (filespec/thename)) + (P("[") * P(true)/isname * (((1-P("]"))^0)/thename) * P("]")) +local fontname   = (P("name:")/isname * (namespec/thename)) + P(true)/issome * (namespec/thename) +local sometext   = (R("az","AZ","09") + S("+-.,"))^1 +local truevalue  = P("+") * spaces * (sometext/istrue) +local falsevalue = P("-") * spaces * (sometext/isfalse) +local keyvalue   = P("+") + (C(sometext) * spaces * P("=") * spaces * C(sometext))/iskey +local somevalue  = sometext/istrue +local subvalue   = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim +local option     = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces +local options    = P(":") * spaces * (P(";")^0  * option)^0 +local pattern    = (filename + fontname) * subvalue^0 * stylespec^0 * options^0 + +local function colonized(specification) -- xetex mode +    feature_list = { } +    lpeg.match(pattern,specification.specification) +    set_default_features(feature_list.script) +    if feature_list.style then +        specification.style = feature_list.style +        feature_list.style = nil +    end +    if feature_list.optsize then +        specification.optsize = feature_list.optsize +        feature_list.optsize = nil +    end +    if feature_list.name then +        if resolvers.findfile(feature_list.name, "tfm") then +            feature_list.lookup = "file" +            feature_list.name   = file.addsuffix(feature_list.name, "tfm") +        elseif resolvers.findfile(feature_list.name, "ofm") then +            feature_list.lookup = "file" +            feature_list.name   = file.addsuffix(feature_list.name, "ofm") +        end + +        specification.name = feature_list.name +        feature_list.name = nil +    end +    if feature_list.lookup then +        specification.lookup = feature_list.lookup +        feature_list.lookup = nil +    end +    if feature_list.sub then +        specification.sub = feature_list.sub +        feature_list.sub = nil +    end +    if not feature_list.mode then +        -- if no mode is set, use our default +        feature_list.mode = fonts.mode +    end +    specification.features.normal = fonts.handlers.otf.features.normalize(feature_list) +    return specification +end + +fonts.definers.registersplit(":",colonized,"cryptic") +fonts.definers.registersplit("", colonized,"more cryptic") -- catches \font\text=[names] + +function fonts.definers.applypostprocessors(tfmdata) +    local postprocessors = tfmdata.postprocessors +    if postprocessors then +        for i=1,#postprocessors do +            local extrahash = postprocessors[i](tfmdata) -- after scaling etc +            if type(extrahash) == "string" and extrahash ~= "" then +                -- e.g. a reencoding needs this +                extrahash = string.gsub(lower(extrahash),"[^a-z]","-") +                tfmdata.properties.fullname = format("%s-%s",tfmdata.properties.fullname,extrahash) +            end +        end +    end +    return tfmdata +end +---[[ end included font-ltx.lua ]] + +--[[doc-- +This uses the code from luatex-fonts-merged (<- font-otc.lua) instead +of the removed luaotfload-font-otc.lua. + +TODO find out how far we get setting features without these lines, +relying on luatex-fonts only (it *does* handle features somehow, after +all). +--doc]]-- + +-- we assume that the other otf stuff is loaded already + +---[[ begin snippet from font-otc.lua ]] +local trace_loading       = false  trackers.register("otf.loading", function(v) trace_loading = v end) +local report_otf          = logs.reporter("fonts","otf loading") + +local otf                 = fonts.handlers.otf +local registerotffeature  = otf.features.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("registering feature %a, affected glyphs %a, skipped glyphs %a",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) + +---[[ end snippet from font-otc.lua ]] + +local tlig = { +    { +        type      = "substitution", +        features  = everywhere, +        data      = { +            [0x0022] = 0x201D,                   -- quotedblright +            [0x0027] = 0x2019,                   -- quoteleft +            [0x0060] = 0x2018,                   -- quoteright +        }, +        flags     = { }, +    }, +    { +        type     = "ligature", +        features = everywhere, +        data     = { +            [0x2013] = {0x002D, 0x002D},         -- endash +            [0x2014] = {0x002D, 0x002D, 0x002D}, -- emdash +            [0x201C] = {0x2018, 0x2018},         -- quotedblleft +            [0x201D] = {0x2019, 0x2019},         -- quotedblright +            [0x201E] = {0x002C, 0x002C},         -- quotedblbase +            [0x00A1] = {0x0021, 0x2018},         -- exclamdown +            [0x00BF] = {0x003F, 0x2018},         -- questiondown +        }, +        flags    = { }, +    }, +    { +        type     = "ligature", +        features = everywhere, +        data     = { +            [0x201C] = {0x0060, 0x0060},         -- quotedblleft +            [0x201D] = {0x0027, 0x0027},         -- quotedblright +            [0x00A1] = {0x0021, 0x0060},         -- exclamdown +            [0x00BF] = {0x003F, 0x0060},         -- questiondown +        }, +        flags    = { }, +    }, +} + +otf.addfeature("tlig", tlig) +otf.addfeature("trep", { }) -- empty, all in tlig now + +local anum_arabic = { --- these are the same as in font-otc +    [0x0030] = 0x0660, +    [0x0031] = 0x0661, +    [0x0032] = 0x0662, +    [0x0033] = 0x0663, +    [0x0034] = 0x0664, +    [0x0035] = 0x0665, +    [0x0036] = 0x0666, +    [0x0037] = 0x0667, +    [0x0038] = 0x0668, +    [0x0039] = 0x0669, +} + +local anum_persian = {--- these are the same as in font-otc +    [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 = { far = true, urd = true, snd = true } }, +        data     = anum_persian, +        flags    = { }, +        valid    = valid, +    }, +    { +        type     = "substitution", +        features = { arab = { ["*"] = true } }, +        data     = anum_arabic, +        flags    = { }, +        valid    = valid, +    }, +} + +--- below the specifications as given in the removed font-otc.lua +--- the rest was identical to what this file had from the beginning +--- both make the “anum.tex” test pass anyways +-- +--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) + +registerotffeature { +    name        = 'anum', +    description = 'arabic digits', +} + +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 + +-- vim:tw=71:sw=4:ts=4:expandtab diff --git a/otfl-fonts-cbk.lua b/luaotfload-fonts-cbk.lua index 9db94f6..9db94f6 100644 --- a/otfl-fonts-cbk.lua +++ b/luaotfload-fonts-cbk.lua diff --git a/otfl-fonts-def.lua b/luaotfload-fonts-def.lua index 0c2f0db..0c2f0db 100644 --- a/otfl-fonts-def.lua +++ b/luaotfload-fonts-def.lua diff --git a/otfl-fonts-enc.lua b/luaotfload-fonts-enc.lua index e20c3a0..e20c3a0 100644 --- a/otfl-fonts-enc.lua +++ b/luaotfload-fonts-enc.lua diff --git a/otfl-fonts-ext.lua b/luaotfload-fonts-ext.lua index b60d045..b60d045 100644 --- a/otfl-fonts-ext.lua +++ b/luaotfload-fonts-ext.lua diff --git a/otfl-fonts-lua.lua b/luaotfload-fonts-lua.lua index ec3fe38..ec3fe38 100644 --- a/otfl-fonts-lua.lua +++ b/luaotfload-fonts-lua.lua diff --git a/otfl-fonts-tfm.lua b/luaotfload-fonts-tfm.lua index b9bb1bd..b9bb1bd 100644 --- a/otfl-fonts-tfm.lua +++ b/luaotfload-fonts-tfm.lua diff --git a/otfl-lib-dir.lua b/luaotfload-lib-dir.lua index 00cda38..00cda38 100644 --- a/otfl-lib-dir.lua +++ b/luaotfload-lib-dir.lua diff --git a/otfl-font-pfb.lua b/luaotfload-loaders.lua index 8ab6b29..8ab6b29 100644 --- a/otfl-font-pfb.lua +++ b/luaotfload-loaders.lua diff --git a/otfl-fonts-merged.lua b/luaotfload-merged.lua index 314305a..314305a 100644 --- a/otfl-fonts-merged.lua +++ b/luaotfload-merged.lua diff --git a/otfl-luat-ovr.lua b/luaotfload-override.lua index bd04eeb..94f2376 100644 --- a/otfl-luat-ovr.lua +++ b/luaotfload-override.lua @@ -35,7 +35,8 @@ local set_loglevel = function (n)          loglevel = n      end  end -logs.set_loglevel = set_loglevel +logs.set_loglevel   = set_loglevel +logs.set_log_level  = set_loglevel --- accomodating lazy typists  local set_logout = function (s)      if s == "stdout" then diff --git a/luaotfload.dtx b/luaotfload.dtx index f86d9b7..7c74a37 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -315,7 +315,7 @@ and the derived files  % The next example shows how to load the \emphasis{Porson} font digitized by  % the Greek Font Society using \XETEX-style syntax and an absolute path from a  % non-standard directory: -%  +%  % \begin{quote}  %   \begin{verbatim}  %   \font\gfsporson="[/tmp/GFSPorson.otf]" at 12pt @@ -486,7 +486,7 @@ and the derived files  %        Their arguments are names of \LUA tables that contain  %        values for the respective features.\footnote{%  %           For examples of the table layout please refer to the -%           section of the file \fileent{otfl-fonts-ext.lua} where the +%           section of the file \fileent{luaotfload-fonts-ext.lua} where the  %           default values are defined.  %           Alternatively and with loss of information, you can dump  %           those tables into your terminal by issuing @@ -701,7 +701,7 @@ and the derived files  % approximate matching.  % Suppose you cannot precisely remember if the variant of  % \identifier{Iwona} you are looking for was “Bright” or “Light”. -% The query  +% The query  %  % \begin{quote}  %   \begin{verbatim} @@ -724,7 +724,7 @@ and the derived files  % \LUATEX reference manual.\footnote{%  %   In \TEX Live: \fileent{texmf-dist/doc/luatex/base/luatexref-t.pdf}.  % } -%   +%  % \verb|fontdbutil --help| will list the available command line  % switches, including some not discussed in detail here.  % @@ -737,7 +737,7 @@ and the derived files  % running \verb|fontdbutil -v| to increase verbosity.  % Take a note of the \emphasis{filename} of the font that database  % creation fails with and append it to the file -% \fileent{otfl-blacklist.cnf}. +% \fileent{luaotfload-blacklist.cnf}.  %  % A blacklist file is a list of font filenames, one per line.  % Specifying the full path to where the file is located is optional, the @@ -754,8 +754,8 @@ and the derived files  % }  % or just leave it in the working directory of your document.  % \identifier{luaotfload} reads all files named -% \fileent{otfl-blacklist.cnf} it finds, so the fonts in -% \fileent{./otfl-blacklist.cnf} extend the global blacklist. +% \fileent{luaotfload-blacklist.cnf} it finds, so the fonts in +% \fileent{./luaotfload-blacklist.cnf} extend the global blacklist.  %  % Furthermore, a filename prepended with a dash character (|-|) is  % removed from the blacklist, causing it to be temporarily whitelisted @@ -801,102 +801,87 @@ and the derived files  % \identifier{luaotfload} in one way or the other.  % See figure \ref{file-graph} on page \pageref{file-graph} for a  % graphical representation of the dependencies. -% From \LUATEX-Fonts the following files have been imported: +% From \LUATEX-Fonts, only the file \fileent{luatex-fonts-merged.lua} +% has been imported as \fileent{luaotfload-merged.lua}. +% It is generated by \fileent{mtx-package}, a \LUA source code merging +% too developed by Hans Hagen.\footnote{% +%   \fileent{mtx-package} is +%   \href +%     {http://repo.or.cz/w/context.git/blob_plain/refs/heads/origin:/scripts/context/lua/mtx-package.lua} +%     {part of \CONTEXT} +%   and requires \fileent{mtxrun}. +%   Run +%   \verb|mtxrun --script package --help| +%   to display further information. +%   For the actual merging code see the file +%   \fileent{util-mrg.lua} that is part of \CONTEXT. +% } +% It houses several \LUA files that can be classed in three +% categories.  %  %   \begin{itemize}  %     \let\normalitem=\item -%     \def\fileitem#1#2{% -%       \normalitem{\fileent{#1}}% -%       \hfill -%       (as \fileent{\itshape#2})% -%       \break -%     }  %     \def\incitem#1{%  %       \normalitem{\fileent{#1}}  %     } -%     \fileitem{luatex-fonts.lua}{otfl-fonts.lua} -%           The wrapper that loads the font loader code. -% -%     \fileitem{luatex-fonts-merged.lua}{otfl-fonts-merged.lua} -%           The font loader package. -%           It is generated by \fileent{mtx-package}, a \LUA -%           source code merging tool developed by Hans -%           Hagen.\footnote{% -%             \fileent{mtx-package} is -%             \href -%               {http://repo.or.cz/w/context.git/blob_plain/refs/heads/origin:/scripts/context/lua/mtx-package.lua} -%               {part of \CONTEXT} -%             and requires \fileent{mtxrun}. -%             Run -%             \verb|mtxrun --script package --help| -%             to display further information. -%             For the actual merging code see the file -%             \fileent{util-mrg.lua} that is part of \CONTEXT. -%           } -% -%           Included are several Lua files that can be classed in three -%           categories. -%           \begin{itemize} -%             \normalitem \emphasis{\LUA utility libraries}, a subset -%                         of what is provided by the \identifier{lualibs} -%                         package. -% -%                         \begin{multicols}{2} -%                           \begin{itemize} -%                             \incitem{l-lua.lua}       \incitem{l-lpeg.lua} -%                             \incitem{l-function.lua}  \incitem{l-string.lua} -%                             \incitem{l-table.lua}     \incitem{l-io.lua} -%                             \incitem{l-file.lua}      \incitem{l-boolean.lua} -%                             \incitem{l-math.lua}      \incitem{util-str.lua} -%                           \end{itemize} -%                         \end{multicols} -% -%             \normalitem The \emphasis{font loader} itself. -%                         These files have been written for -%                         \LUATEX-Fonts and they are distributed along -%                         with \identifier{luaotfload}. -%                         \begin{multicols}{2} -%                           \begin{itemize} -%                             \incitem{luatex-basics-gen.lua} -%                             \incitem{luatex-basics-nod.lua} -%                             \incitem{luatex-fonts-enc.lua} -%                             \incitem{luatex-fonts-syn.lua} -%                             \incitem{luatex-fonts-tfm.lua} -%                             \incitem{luatex-fonts-chr.lua} -%                             \incitem{luatex-fonts-lua.lua} -%                             \incitem{luatex-fonts-def.lua} -%                             \incitem{luatex-fonts-ext.lua} -%                             \incitem{luatex-fonts-cbk.lua} -%                           \end{itemize} -%                         \end{multicols} -% -%             \normalitem Code related to \emphasis{font handling and -%                         node processing}, taken directly from -%                         \CONTEXT. -%                         \begin{multicols}{2} -%                           \begin{itemize} -%                             \incitem{data-con.lua} \incitem{font-ini.lua} -%                             \incitem{font-con.lua} \incitem{font-cid.lua} -%                             \incitem{font-map.lua} \incitem{font-oti.lua} -%                             \incitem{font-otf.lua} \incitem{font-otb.lua} -%                             \incitem{node-inj.lua} \incitem{font-ota.lua} -%                             \incitem{font-otn.lua} \incitem{font-def.lua} -%                           \end{itemize} -%                         \end{multicols} -%           \end{itemize} -% -%           Note that if \identifier{luaotfload} cannot locate the -%           merged file, it will load the individual \LUA libraries -%           instead. -%           Their names remain the same as in \CONTEXT (without the -%           \verb|otfl|-prefix) since they are hard-coded in -%           \fileent{otfl-fonts.lua}. -%           Thus if you prefer running bleeding edge code from the -%           \CONTEXT beta, all you have to do is remove -%           \fileent{otfl-fonts-merged.lua} from the search path. -% +%     \normalitem \emphasis{\LUA utility libraries}, a subset +%                 of what is provided by the \identifier{lualibs} +%                 package. +% +%                 \begin{multicols}{2} +%                   \begin{itemize} +%                     \incitem{l-lua.lua}       \incitem{l-lpeg.lua} +%                     \incitem{l-function.lua}  \incitem{l-string.lua} +%                     \incitem{l-table.lua}     \incitem{l-io.lua} +%                     \incitem{l-file.lua}      \incitem{l-boolean.lua} +%                     \incitem{l-math.lua}      \incitem{util-str.lua} +%                   \end{itemize} +%                 \end{multicols} +% +%     \normalitem The \emphasis{font loader} itself. +%                 These files have been written for +%                 \LUATEX-Fonts and they are distributed along +%                 with \identifier{luaotfload}. +%                 \begin{multicols}{2} +%                   \begin{itemize} +%                     \incitem{luatex-basics-gen.lua} +%                     \incitem{luatex-basics-nod.lua} +%                     \incitem{luatex-fonts-enc.lua} +%                     \incitem{luatex-fonts-syn.lua} +%                     \incitem{luatex-fonts-tfm.lua} +%                     \incitem{luatex-fonts-chr.lua} +%                     \incitem{luatex-fonts-lua.lua} +%                     \incitem{luatex-fonts-def.lua} +%                     \incitem{luatex-fonts-ext.lua} +%                     \incitem{luatex-fonts-cbk.lua} +%                   \end{itemize} +%                 \end{multicols} +% +%     \normalitem Code related to \emphasis{font handling and +%                 node processing}, taken directly from +%                 \CONTEXT. +%                 \begin{multicols}{2} +%                   \begin{itemize} +%                     \incitem{data-con.lua} \incitem{font-ini.lua} +%                     \incitem{font-con.lua} \incitem{font-cid.lua} +%                     \incitem{font-map.lua} \incitem{font-oti.lua} +%                     \incitem{font-otf.lua} \incitem{font-otb.lua} +%                     \incitem{node-inj.lua} \incitem{font-ota.lua} +%                     \incitem{font-otn.lua} \incitem{font-def.lua} +%                   \end{itemize} +%                 \end{multicols}  %   \end{itemize}  % +% Note that if \identifier{luaotfload} cannot locate the +% merged file, it will load the individual \LUA libraries +% instead. +% Their names remain the same as in \CONTEXT (without the +% \verb|otfl|-prefix) since we imported the relevant section of +% \fileent{luatex-fonts.lua} unmodified into \fileent{luaotfload.lua}. +% Thus if you prefer running bleeding edge code from the +% \CONTEXT beta, all you have to do is remove +% \fileent{luaotfload-merged.lua} from the search path. +%  % In addition to these, \identifier{luaotfload} requires a number of  % files not contained in the merge. Some of these have no equivalent in  % \LUATEX-Fonts or \CONTEXT, some were taken unmodified from the @@ -908,26 +893,26 @@ and the derived files  %       \normalitem{\fileent{#1}}%  %       \space--\hskip1em  %     } -%     \ouritem {otfl-font-otc.lua} \fileent{font-otc} from \CONTEXT; +%     \ouritem {luaotfload-font-otc.lua} \fileent{font-otc} from \CONTEXT;  %                                  font feature handling. -%     \ouritem {otfl-lib-dir.lua}  \fileent{l-dir} from \CONTEXT; +%     \ouritem {luaotfload-lib-dir.lua}  \fileent{l-dir} from \CONTEXT;  %                                  contains functionality required -%                                  by \fileent{otfl-font-nms.lua}. -%     \ouritem {otfl-luat-ovr.lua} overrides the \CONTEXT logging +%                                  by \fileent{luaotfload-font-nms.lua}. +%     \ouritem {luaotfload-luat-ovr.lua} overrides the \CONTEXT logging  %                                  functionality. -%     \ouritem {otfl-font-pfb.lua} registers the \OpenType +%     \ouritem {luaotfload-font-pfb.lua} registers the \OpenType  %                                  font reader as handler for  %                                  Postscript fonts. -%     \ouritem {otfl-font-nms.lua} font database. -%     \ouritem {otfl-font-clr.lua} color handling. -%     \ouritem {otfl-font-ltx.lua} font feature handling. -%     \ouritem {otfl-features.lua} definitions of the \verb|anum| and +%     \ouritem {luaotfload-font-nms.lua} font database. +%     \ouritem {luaotfload-font-clr.lua} color handling. +%     \ouritem {luaotfload-font-ltx.lua} font feature handling. +%     \ouritem {luaotfload-features.lua} definitions of the \verb|anum| and  %                                  \verb|tlig| features.  % \end{itemize}  %  % \begin{figure}[b] -%   \caption{Schematic of the Files in \identifier{Luaotfload}} -%   \includegraphics[width=\textheight,angle=90]{filegraph.pdf} +%   \caption{Schematic of the files in \identifier{Luaotfload}} +%   \includegraphics[width=\textwidth]{filegraph.pdf}  %   \label{file-graph}  % \end{figure}  % @@ -990,7 +975,12 @@ and the derived files  %<*lua>  % \fi  %    \begin{macrocode} -luaotfload = luaotfload or {} +luaotfload                  = luaotfload or {} +local luaotfload            = luaotfload + +config                      = config or { } +config.luaotfload           = config.luaotfload or { } +luaotfload.prefer_merge     = config.luaotfload.prefer_merge or true  luaotfload.module = {      name          = "luaotfload", @@ -1005,9 +995,11 @@ luaotfload.module = {  local luatexbase = luatexbase  local type, next       = type, next +local setmetatable     = setmetatable  local stringfind       = string.find  local stringsub        = string.sub  local stringmatch      = string.match +local stringformat     = string.format  local find_file        = kpse.find_file  local add_to_callback, create_callback = @@ -1018,14 +1010,14 @@ local reset_callback, call_callback =  local dummy_function = function () end  %    \end{macrocode} -% -%    No final decision has been made on how to handle font definition.  At -%    the moment, there are three candidates: The \identifier{generic} -%    callback as hard-coded in the font loader, the \identifier{old} -%    wrapper, and a simplified version of the latter (\identifier{patch}) -%    that does nothing besides applying font patches. +% No final decision has been made on how to handle font definition.  At +% the moment, there are three candidates: The \identifier{generic} +% callback as hard-coded in the font loader, the \identifier{old} +% wrapper, and a simplified version of the latter (\identifier{patch}) +% that does nothing besides applying font patches.  %  %    \begin{macrocode} +  luaotfload.font_definer = "patch" --- | “generic” | “old”  local error, warning, info, log = @@ -1047,28 +1039,25 @@ if tex.luatexversion < luatex_version then  end  %    \end{macrocode} -% -%    \subsection{Module loading} -% -%    We load the files imported from \CONTEXT with this function. -%    It automatically prepends the prefix \fileent{otfl-} to its argument, -%    so we can refer to the files with their actual \CONTEXT name. +% \subsection{Module loading} +% We load the files imported from \CONTEXT with this function. +% It automatically prepends the prefix \fileent{luaotfload-} to its +% argument, so we can refer to the files with their actual \CONTEXT name.  %  %    \begin{macrocode} -local fl_prefix = "otfl" -- “luatex” for luatex-plain +local fl_prefix = "luaotfload" -- “luatex” for luatex-plain  local loadmodule = function (name)      require(fl_prefix .."-"..name)  end  %    \end{macrocode} -% -%    Before \TeX Live 2013 version, \LUATEX had a bug that made ofm fonts fail -%    when called with their extension. There was a side-effect making ofm -%    totally unloadable when luaotfload was present. The following lines are -%    a patch for this bug. The utility of these lines is questionable as they -%    are not necessary since \TeX Live 2013. They should be removed in the next -%    version. +% Before \TeX Live 2013 version, \LUATEX had a bug that made ofm fonts fail +% when called with their extension. There was a side-effect making ofm +% totally unloadable when luaotfload was present. The following lines are +% a patch for this bug. The utility of these lines is questionable as they +% are not necessary since \TeX Live 2013. They should be removed in the next +% version.  %  %    \begin{macrocode}  local Cs, P, lpegmatch = lpeg.Cs, lpeg.P, lpeg.match @@ -1089,208 +1078,235 @@ local find_vf_file = function (name)      return fullname  end ---[[-- keep --]] ---- from Hans (all merged): - ----   file name              modified  include name ---- × basics-gen.lua         t         luat-basics-gen ---- × font-def -> fonts-def  t         luatex-font-def (there’s also the normal font-def!) ---- × fonts-enc              f         luatex-font-enc ---- × fonts-ext              t         luatex-fonts-ext ---- × fonts-lua              f         luatex-fonts-lua ----   fonts-tfm              f         luatex-fonts-tfm ---- × fonts-cbk              f         luatex-fonts-lua - ---- from Hans (unmerged): ----   font-otc.lua -> otfl-font-otc.lua - ---- from luaotfload: ----   otfl-luat-ovr.lua    -- override some luat-dum functions ----   otfl-font-clr.lua ----   otfl-font-ltx.lua ----   otfl-font-nms.lua ----   otfl-font-pfb.lua    -- ? - ---[[-- new --]] ---- basics-nod          (merged as fonts-nod !) ---- fonts-demo-vf-1.lua ---- fonts-syn           (merged) - ---[[-- merged, to be dropped --]] ---- otfl-data-con.lua ---- otfl-font-cid.lua ---- otfl-font-con.lua ---- otfl-font-ini.lua ---- otfl-font-ota.lua ---- otfl-font-otb.lua ---- otfl-font-otf.lua ---- otfl-font-oti.lua ---- otfl-font-otn.lua -  %    \end{macrocode} -% -% -%    \subsection{Preparing the Font Loader} -%    We treat the fontloader as a black box so behavior is consistent -%    between formats. -%    The wrapper file is \fileent{otfl-fonts.lua} which we imported from -%    \href{http://standalone.contextgarden.net/current/context/experimental/tex/generic/context/luatex/}{\LUATEX-Plain}. -%    It has roughly two purposes: -% -%    \begin{enumerate} -% -%       \item insert the functionality required for fontloader; and -% -%       \item put it in place via the respective callbacks. -% -%    \end{enumerate} -% -%    How the first step is executed depends on the presence on the -%    \emphasis{merged font loader code}. -%    In \identifier{luaotfload} this is contained in the file -%    \fileent{otfl-fonts-merged.lua}. -%    If this file cannot be found,  the original libraries from \CONTEXT of -%    which the merged code was composed are loaded instead. -% -%    Hans provides two global tables to control the font loader: -% -%      \begin{itemize} -%        \item  \luafunction{generic_context}: -%               encapsulation mechanism, callback functions -%        \item  \luafunction{non generic_context}: -%               customized code insertion -%      \end{itemize} -% -%    With \luafunction{non_generic_context} we can tailor the font loader -%    insertion to our file naming habits (key \luafunction{load_before}). -%    Additionally, \luafunction{skip_loading} can be unset to force loading -%    of the original libraries as though the merged code was absent. -%    Another key, \luafunction{load_after} is called at the time when the -%    font loader is actually inserted. -%    In combination with the option \luafunction{no_callbacks_yet} in -%    \luafunction{generic_context}, we can insert our own, -%    \identifier{luatexbase}-style callback handling here. +% \subsection{Preparing the Font Loader} +% We treat the fontloader as a black box so behavior is consistent +% between formats. +% We do no longer run the intermediate wrapper file +% \fileent{luaotfload-fonts.lua} which we used to import from +% \href{http://standalone.contextgarden.net/current/context/experimental/tex/generic/context/luatex/}{\LUATEX-Plain}. +% Rather, we load the fontloader code directly in the same fashion as +% \identifier{luatex-fonts}. +% How this is executed depends on the presence on the \emphasis{merged +% font loader code}. +% In \identifier{luaotfload} this is contained in the file +% \fileent{luaotfload-merged.lua}. +% If this file cannot be found, the original libraries from \CONTEXT of +% which the merged code was composed are loaded instead. +% +% The imported font loader will call \luafunction{callback.register} once +% while reading \fileent{font-def.lua}. +% This is unavoidable unless we modify the imported files, but harmless +% if we make it call a dummy instead. +% However, this problem might vanish if we decide to do the merging +% ourselves, like the \identifier{lualibs} package does. +% With this step we would obtain the freedom to load our own overrides in +% the process right where they are needed, at the cost of losing +% encapsulation. +% The decision on how to progress is currently on indefinite hold.  %  %    \begin{macrocode} -generic_context = {no_callbacks_yet = true} -non_generic_context = { luatex_fonts = { -        load_before     = "otfl-fonts-merged.lua", -        -- load_after      = nil, --- TODO, this is meant for callbacks -        skip_loading    = true, -}} +local starttime = os.gettimeofday() + +local trapped_register  = callback.register +callback.register       = dummy_function  %    \end{macrocode} -% -%    The imported font loader will call \luafunction{callback.register} once -%    while reading \fileent{font-def.lua}. -%    This is unavoidable unless we modify the imported files, but harmless -%    if we make it call a dummy instead. +% By default, the fontloader requires a number of \emphasis{private +% attributes} for internal use. +% These must be kept consistent with the attribute handling methods as +% provided by \identifier{luatexbase}. +% Our strategy is to override the function that allocates new attributes +% before we initialize the font loader, making it a wrapper around +% \luafunction{luatexbase.new_attribute}.\footnote{% +%     Many thanks, again, to Hans Hagen for making this part +%     configurable! +% } +% The attribute identifiers are prefixed “\fileent{luaotfload@}” to +% avoid name clashes.  %  %    \begin{macrocode} -local trapped_register = callback.register -callback.register      = dummy_function +do +    local new_attribute    = luatexbase.new_attribute +    local the_attributes   = luatexbase.attributes + +    attributes = attributes or { } + +    attributes.private = function (name) +        local attr   = "luaotfload@" .. name --- used to be: “otfl@” +        local number = the_attributes[attr] +        if not number then +            number = new_attribute(attr) +        end +        return number +    end +end  %    \end{macrocode} -% -%    In order to have an output with normal verbosity, we need to pre-override -%    some \CONTEXT log function: +% These next lines replicate the behavior of \fileent{luatex-fonts.lua}.  %  %    \begin{macrocode} -local dummylogfunction=function() end -local dummylogreporter=function(c) return function(...) log(string.formatters(...)) end end +local context_environment = { } -logs={ -  new=dummylogreporter, -  reporter=dummylogreporter, -  messenger=dummylogreporter, -  report=dummylogfunction, -} +local push_namespaces = function () +    log("push namespace for font loader") +    local normalglobal = { } +    for k, v in next, _G do +        normalglobal[k] = v +    end +    return normalglobal +end + +local pop_namespaces = function (normalglobal, isolate) +    if normalglobal then +        local _G = _G +        local mode = "non-destructive" +        if isolate then mode = "destructive" end +        log("pop namespace from font loader -- "..mode) +        for k, v in next, _G do +            if not normalglobal[k] then +                context_environment[k] = v +                if isolate then +                    _G[k] = nil +                end +            end +        end +        for k, v in next, normalglobal do +            _G[k] = v +        end +        -- just to be sure: +        setmetatable(context_environment,_G) +    else +        log("irrecoverable error during pop_namespace: no globals to restore") +        os.exit() +    end +end + +luaotfload.context_environment  = context_environment +luaotfload.push_namespaces      = push_namespaces +luaotfload.pop_namespaces       = pop_namespaces + +local our_environment = push_namespaces()  %    \end{macrocode} -% -%    Now that things are sorted out we can finally load the fontloader. +% The font loader requires that the attribute with index zero be zero. +% We happily oblige. +% (Cf. \fileent{luatex-fonts-nod.lua}.)  %  %    \begin{macrocode} -loadmodule"fonts.lua" +tex.attribute[0] = 0  %    \end{macrocode} -% -%    By default, the fontloader requires a number of \emphasis{private -%    attributes} for internal use. -%    These must be kept consistent with the attribute handling methods as -%    provided by \identifier{luatexbase}. -%    Our strategy is to override the function that allocates new attributes -%    before we initialize the font loader, making it a wrapper around -%    \luafunction{luatexbase.new_attribute}.\footnote{% -%        Many thanks, again, to Hans Hagen for making this part -%        configurable! -%    } -%    The attribute identifiers are prefixed “\fileent{otfl@}” to -%    avoid name clashes. +% Now that things are sorted out we can finally load the fontloader.  %  %    \begin{macrocode} -do -    local new_attribute = luatexbase.new_attribute -    local the_attributes = luatexbase.attributes +loadmodule"merged.lua" -    attributes = attributes or { } +if fonts then -    attributes.private = function (name) -        local attr   = "otfl@" .. name -        local number = the_attributes[attr] -        if not number then -            number = new_attribute(attr) -        end -        return number +    if not fonts._merge_loaded_message_done_ then +        --- a program talking first person -- HH sure believes in strong AI ... +        log[[“I am using the merged version of 'luaotfload.lua' here. If]] +        log[[ you run into problems or experience unexpected behaviour,]] +        log[[ and if you have ConTeXt installed you can try to delete the]] +        log[[ file 'luaotfload-font-merged.lua' as I might then use the]] +        log[[ possibly updated libraries. The merged version is not]] +        log[[ supported as it is a frozen instance. Problems can be]] +        log[[ reported to the ConTeXt mailing list.”]]      end -end +    fonts._merge_loaded_message_done_ = true + +else--- the loading sequence is known to change, so this might have to +    --- be updated with future updates! +    --- do not modify it though unless there is a change to the merged +    --- package! +    loadmodule("l-lua.lua") +    loadmodule("l-lpeg.lua") +    loadmodule("l-function.lua") +    loadmodule("l-string.lua") +    loadmodule("l-table.lua") +    loadmodule("l-io.lua") +    loadmodule("l-file.lua") +    loadmodule("l-boolean.lua") +    loadmodule("l-math.lua") +    loadmodule("util-str.lua") +    loadmodule('luatex-basics-gen.lua') +    loadmodule('data-con.lua') +    loadmodule('luatex-basics-nod.lua') +    loadmodule('font-ini.lua') +    loadmodule('font-con.lua') +    loadmodule('luatex-fonts-enc.lua') +    loadmodule('font-cid.lua') +    loadmodule('font-map.lua') +    loadmodule('luatex-fonts-syn.lua') +    loadmodule('luatex-fonts-tfm.lua') +    loadmodule('font-oti.lua') +    loadmodule('font-otf.lua') +    loadmodule('font-otb.lua') +    loadmodule('node-inj.lua') +    loadmodule('font-ota.lua') +    loadmodule('font-otn.lua') +    loadmodule('luatex-fonts-lua.lua') +    loadmodule('font-def.lua') +    loadmodule('luatex-fonts-def.lua') +    loadmodule('luatex-fonts-ext.lua') +    loadmodule('luatex-fonts-cbk.lua') +end --- non-merge fallback scope  %    \end{macrocode} +% Here we adjust the globals created during font loader initialization. +% If the second argument to \luafunction{pop_namespaces()} is \verb|true| +% this will restore the state of \luafunction{_G}, eliminating every +% global generated since the last call to \luafunction{push_namespaces()}. +% At the moment we see no reason to do this, and since the font loader is +% considered an essential part of \identifier{luatex} as well as a very +% well organized piece of code, we happily concede it the right to add to +% \luafunction{_G} if needed.  % -% -%    \subsection{Callbacks} -% -%    After the fontloader is ready we can restore the callback trap from -%    \identifier{luatexbase}. +%    \begin{macrocode} + +pop_namespaces(our_environment, false)-- true) + +log("fontloader loaded in %0.3f seconds", os.gettimeofday()-starttime) + +%    \end{macrocode} +% \subsection{Callbacks} +% After the fontloader is ready we can restore the callback trap from +% \identifier{luatexbase}.  %  %    \begin{macrocode}  callback.register = trapped_register  %    \end{macrocode} -% -%    We do our own callback handling with the means provided by luatexbase. -% -%    Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter} -%    are coupled in \CONTEXT in the concept of \emphasis{node processor}. +% We do our own callback handling with the means provided by luatexbase. +% Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter} +% are coupled in \CONTEXT in the concept of \emphasis{node processor}.  %  %    \begin{macrocode}  add_to_callback("pre_linebreak_filter", -                generic_context.callback_pre_linebreak_filter, +                nodes.simple_font_handler,                  "luaotfload.node_processor",                  1)  add_to_callback("hpack_filter", -                generic_context.callback_hpack_filter, +                nodes.simple_font_handler,                  "luaotfload.node_processor",                  1)  add_to_callback("find_vf_file",                  find_vf_file, "luaotfload.find_vf_file") -loadmodule"font-otc.lua"   -- TODO check what we can drop from otfl-features -loadmodule"lib-dir.lua"    -- required by font-nms -loadmodule"luat-ovr.lua" +loadmodule"lib-dir.lua"   --- required by luaofload-database.lua +loadmodule"override.lua"  --- “luat-ovr”  %    \end{macrocode} -% -% -%    \CONTEXT does not support ofm, these lines were added in order to make it -%    work. However they do not seem necessary so they are commented for now. +% \CONTEXT does not support ofm, these lines were added in order to make it +% work. However they do not seem necessary so they are commented for now.  %  %    \begin{macrocode}  -- if fonts and fonts.readers.tfm then @@ -1300,57 +1316,47 @@ loadmodule"luat-ovr.lua"  --  --- fonts.readers.sequence[#fonts.readers.sequence+1] = "ofm"  --end  %    \end{macrocode} -% -% -%    Now we load the modules written for \identifier{luaotfload}. +% Now we load the modules written for \identifier{luaotfload}.  %  %    \begin{macrocode} -loadmodule"font-pfb.lua"    --- new in 2.0, added 2011 -loadmodule"font-nms.lua" -loadmodule"font-clr.lua" -loadmodule"font-ltx.lua"    --- new in 2.0, added 2011 +loadmodule"loaders.lua"    --- “font-pfb” new in 2.0, added 2011 +loadmodule"database.lua"   --- “font-nms” +loadmodule"colors.lua"     --- “font-clr”  %    \end{macrocode} -% -% -%    This hack makes fonts called with file method found by fonts.names.resove -%    instead of just trying to find them with kpse. It is necessary in case -%    of fonts that are not accessible by kpse but present in the database, a  -%    quite common case under Linux. +% This hack makes fonts called with file method found by fonts.names.resolve +% instead of just trying to find them with kpse. It is necessary in case +% of fonts that are not accessible by kpse but present in the database, a +% quite common case under Linux.  %  %    \begin{macrocode} -fonts.definers.resolvers.file = function (specification)  -  specification.name = fonts.names.resolve('', '', specification)  +fonts.definers.resolvers.file = function (specification) +  specification.name = fonts.names.resolve('', '', specification)  end  %    \end{macrocode} -% -% -%    We create a callback for patching fonts on the fly, to be used by other -%    packages. -%    It initially contains the empty function that we are going to override -%    below. +% We create a callback for patching fonts on the fly, to be used by other +% packages. +% It initially contains the empty function that we are going to override +% below.  %  %    \begin{macrocode}  create_callback("luaotfload.patch_font", "simple", dummy_function)  %    \end{macrocode} -% -% -%    This is a wrapper for the imported font loader. -%    As of 2013, everything it does appear to be redundand, so we won’t use -%    it unless somebody points out a cogent reason. -%    Nevertheless, it has been adapted to work with the current structure of -%    font data objects and will stay here for reference / until breakage is -%    reported. -% -%    \emphasis{TODO} -%    This one also enables patching fonts. -%    The current fontloader apparently comes with a dedicated mechanism for -%    that already: enhancers. -%    How those work remains to be figured out. +% This is a wrapper for the imported font loader. +% As of 2013, everything it does appear to be redundand, so we won’t use +% it unless somebody points out a cogent reason. +% Nevertheless, it has been adapted to work with the current structure of +% font data objects and will stay here for reference / until breakage is +% reported. +% \emphasis{TODO} +% This one also enables patching fonts. +% The current fontloader apparently comes with a dedicated mechanism for +% that already: enhancers. +% How those work remains to be figured out.  %  %    \begin{macrocode}  local define_font_wrapper = function (...) @@ -1388,12 +1394,9 @@ local define_font_wrapper = function (...)  end  %    \end{macrocode} -% -% -%    \subsection{\CONTEXT override} -% -%    We provide a simplified version of the original font definition -%    callback. +% \subsection{\CONTEXT override} +% We provide a simplified version of the original font definition +% callback.  %  %    \begin{macrocode} @@ -1403,6 +1406,7 @@ local patch_defined_font = function (...)      if type(tfmdata) == "table" then          call_callback("luaotfload.patch_font", tfmdata)      end +    -- inspect(table.keys(tfmdata))      return tfmdata  end @@ -1411,8 +1415,7 @@ caches.compilemethod = "both"  reset_callback("define_font")  %    \end{macrocode} -% -%    Finally we register the callbacks +% Finally we register the callbacks.  %  %    \begin{macrocode} @@ -1423,7 +1426,7 @@ if luaotfload.font_definer == "old"  then                    1)  elseif luaotfload.font_definer == "generic"  then    add_to_callback("define_font", -                  generic_context.callback_define_font, +                  fonts.definers.read,                    "luaotfload.define_font",                    1)  elseif luaotfload.font_definer == "patch"  then @@ -1465,10 +1468,11 @@ do  end  --]]-- -loadmodule"features.lua" +loadmodule"features.lua" --- contains what was “font-ltx” and “font-otc”  -- vim:tw=71:sw=4:ts=4:expandtab +  %    \end{macrocode}  %  % \iffalse @@ -1631,7 +1635,7 @@ loadmodule"features.lua"  %  % \begin{enumerate}  % -% \item  +% \item  % You must cause the modified files to carry prominent notices stating that  % you changed the files and the date of any change.  % diff --git a/luaotfload.lua b/luaotfload.lua deleted file mode 100644 index f11218e..0000000 --- a/luaotfload.lua +++ /dev/null @@ -1,457 +0,0 @@ -module("luaotfload", package.seeall) - -luaotfload.module = { -    name          = "luaotfload", -    version       = 2.2, -    date          = "2013/04/15", -    description   = "OpenType layout system.", -    author        = "Elie Roux & Hans Hagen", -    copyright     = "Elie Roux", -    license       = "CC0" -} - -local luatexbase = luatexbase - -local type, next       = type, next -local stringfind       = string.find -local stringsub        = string.sub -local stringmatch      = string.match -local stringformat     = string.format -local find_file        = kpse.find_file - -local add_to_callback, create_callback = -      luatexbase.add_to_callback, luatexbase.create_callback -local reset_callback, call_callback = -      luatexbase.reset_callback, luatexbase.call_callback - -local dummy_function = function () end - -_G.luaotfload     = _G.luaotfload or { } -local luaotfload  = _G.luaotfload - ---[[doc-- -No final decision has been made on how to handle font definition.  At -the moment, there are three candidates: The \identifier{generic} -callback as hard-coded in the font loader, the \identifier{old} -wrapper, and a simplified version of the latter (\identifier{patch}) -that does nothing besides applying font patches. ---doc]]-- - -luaotfload.font_definer = "patch" --- | “generic” | “old” - -local error, warning, info, log = -    luatexbase.provides_module(luaotfload.module) - ---[[doc-- -This is a necessary initalization in order not to rebuild an existing -font. -Maybe 600 should be replaced by \texmacro{pdfpkresolution} %% (why?) -or \luafunction{texconfig.pk_dpi} (and it should be replaced -dynamically), but we don't have access (yet) to the -\identifier{texconfig} table, so we let it be 600. -Anyway, it does still work fine even if \texmacro{pdfpkresolution} is -changed. ---doc]]-- - -kpse.init_prog("", 600, "/") - ---[[doc-- -We set the minimum version requirement for \LUATEX to v0.74, as it was -the first version to include version 5.2 of the \LUA interpreter. ---doc]]-- - -local luatex_version = 74 - -if tex.luatexversion < luatex_version then -    warning("LuaTeX v%.2f is old, v%.2f is recommended.", -             tex.luatexversion/100, -             luatex_version   /100) -end - ---[[doc-- -\subsection{Module loading} - -We load the files imported from \CONTEXT with this function. -It automatically prepends the prefix \fileent{otfl-} to its argument, -so we can refer to the files with their actual \CONTEXT name. ---doc]]-- - -local fl_prefix = "otfl" -- “luatex” for luatex-plain -local loadmodule = function (name) -    local tofind = fl_prefix .."-"..name -    local found = find_file(tofind,"tex") -    if found then -        log("loading file %s.", found) -        dofile(found) -    else -        error("file %s not found.", tofind) -    end -end - ---[[doc-- -Virtual fonts are resolved via a callback. -\luafunction{find_vf_file} derives the name of the virtual font file -from the filename. -(NB: \CONTEXT handles this likewise in \fileent{font-vf.lua}.) ---doc]]-- -local Cs, P, lpegmatch = lpeg.Cs, lpeg.P, lpeg.match - -local p_dot, p_slash = P".",  P"/" -local p_suffix       = (p_dot * (1 - p_dot - p_slash)^1 * P(-1)) / "" -local p_removesuffix = Cs((p_suffix + 1)^1) - -local find_vf_file = function (name) -    local fullname = find_file(name, "ovf") -    if not fullname then -        --fullname = find_file(file.removesuffix(name), "ovf") -        fullname = find_file(lpegmatch(p_removesuffix, name), "ovf") -    end -    if fullname then -        log("loading virtual font file %s.", fullname) -    end -    return fullname -end - ---[[doc-- - -\subsection{Preparing the Font Loader} -We treat the fontloader as a black box so behavior is consistent -between formats. -The wrapper file is \fileent{otfl-fonts.lua} which we imported from -\href{http://standalone.contextgarden.net/current/context/experimental/tex/generic/context/luatex/}{\LUATEX-Plain}. -It has roughly two purposes: - -\begin{enumerate} - -   \item insert the functionality required for fontloader; and - -   \item put it in place via the respective callbacks. - -\end{enumerate} - -How the first step is executed depends on the presence on the -\emphasis{merged font loader code}. -In \identifier{luaotfload} this is contained in the file -\fileent{otfl-fonts-merged.lua}. -If this file cannot be found,  the original libraries from \CONTEXT of -which the merged code was composed are loaded instead. - -Hans provides two global tables to control the font loader: - -  \begin{itemize} -    \item  \luafunction{generic_context}: -           encapsulation mechanism, callback functions -    \item  \luafunction{non generic_context}: -           customized code insertion -  \end{itemize} - - -With \luafunction{non_generic_context} we can tailor the font loader -insertion to our file naming habits (key \luafunction{load_before}). -Additionally, \luafunction{skip_loading} can be unset to force loading -of the original libraries as though the merged code was absent. -Another key, \luafunction{load_after} is called at the time when the -font loader is actually inserted. -In combination with the option \luafunction{no_callbacks_yet} in -\luafunction{generic_context}, we can insert our own, -\identifier{luatexbase}-style callback handling here. ---doc]]-- -if not _G.    generic_context then _G.    generic_context = { } end -if not _G.non_generic_context then _G.non_generic_context = { } end - -local     generic_context =    generic_context -local non_generic_context =non_generic_context - -generic_context.no_callbacks_yet = true - -_G.non_generic_context = { luatex_fonts = { -        load_before     = "otfl-fonts-merged.lua", -        -- load_after      = nil, --- TODO, this is meant for callbacks -        skip_loading    = true, -}} - ---[[doc-- -In its raw form, the font loader will write to the terminal quite -liberally, not using the proper channels (loggers) even of \CONTEXT. -To make it behave we temporarily replace two functions from the -\luafunction{texio} library with wrappers that redirect output to the -log. -Just in case Hans decides to call \luafunction{texio.write*} with the -optional target parameter (which he doesn’t at the moment), we catch the -first argument and skip it where appropriate. -The originals are backed up and restored after loading -\fileent{otfl-fonts.lua}. - -Should we decide to do our own packaging (we’re capable of that -anyways), this will most likely become unnecessary. ---doc]]-- - -local normal_write, normal_write_nl = texio.write, texio.write_nl - -local log_template = "luaotfload: %s" -local fake_write = function (first, rest) -    if first == "log" or first == "term" then -- ignore -        normal_write("log", stringformat(log_template, rest)) -    else -        normal_write("log", stringformat(log_template, first)) -    end -end -local fake_write_nl = function (first, rest) -    if first == "log" or first == "term" then -- ignore -        normal_write_nl("log", stringformat(log_template, rest)) -    else -        normal_write_nl("log", stringformat(log_template, first, rest)) -    end -end -texio.write, texio.write_nl = fake_write, fake_write_nl - ---[[doc-- -The imported font loader will call \luafunction{callback.register} once -while reading \fileent{font-def.lua}. -This is unavoidable unless we modify the imported files, but harmless -if we make it call a dummy instead. ---doc]]-- - -local trapped_register = callback.register -callback.register      = dummy_function - ---[[doc-- -Now that things are sorted out we can finally load the fontloader. ---doc]]-- - -loadmodule"fonts.lua" - ---[[doc-- -Here we restore the original \luafunction{texio} functions. ---doc]]-- -texio.write, texio.write_nl = normal_write, normal_write_nl - ---[[doc-- -By default, the fontloader requires a number of \emphasis{private -attributes} for internal use. -These must be kept consistent with the attribute handling methods as -provided by \identifier{luatexbase}. -Our strategy is to override the function that allocates new attributes -before we initialize the font loader, making it a wrapper around -\luafunction{luatexbase.new_attribute}.\footnote{% -    Many thanks, again, to Hans Hagen for making this part -    configurable! -} -The attribute identifiers are prefixed “\fileent{otfl@}” to -avoid name clashes. ---doc]]-- - -do -    local new_attribute = luatexbase.new_attribute -    local the_attributes = luatexbase.attributes - -    _G.attributes = _G.attributes or { } - -    _G.attributes.private = function (name) -        local attr   = "otfl@" .. name -        local number = the_attributes[attr] -        if not number then -            number = new_attribute(attr) -        end -        return number -    end -end - ---[[doc-- - -\subsection{Callbacks} - -After the fontloader is ready we can restore the callback trap from -\identifier{luatexbase}. ---doc]]-- - -callback.register = trapped_register - ---[[doc-- -We do our own callback handling with the means provided by luatexbase. - -Note: \luafunction{pre_linebreak_filter} and \luafunction{hpack_filter} -are coupled in \CONTEXT in the concept of \emphasis{node processor}. ---doc]]-- - -add_to_callback("pre_linebreak_filter", -                generic_context.callback_pre_linebreak_filter, -                "luaotfload.node_processor", -                1) -add_to_callback("hpack_filter", -                generic_context.callback_hpack_filter, -                "luaotfload.node_processor", -                1) -add_to_callback("find_vf_file", -                find_vf_file, "luaotfload.find_vf_file") - -loadmodule"font-otc.lua"   -- TODO check what we can drop from otfl-features -loadmodule"lib-dir.lua"    -- required by font-nms -loadmodule"luat-ovr.lua" - -if fonts and fonts.readers.tfm then -  -------------------------------------------------------------------- -  --- OFM; read this first -  -------------------------------------------------------------------- -  --- I can’t quite make out whether this is still relevant -  --- as those ofm fonts always fail, even in the 2011 version -  --- (mktexpk:  don't know how to create bitmap font for omarabb.ofm) -  --- the font loader appears to read ofm like tfm so if this -  --- hack was supposed achieve that, we should excise it anyways -  fonts.readers.ofm  = fonts.readers.tfm -  fonts.handlers.ofm = fonts.handlers.tfm --- empty anyways -  fonts.formats.ofm  = fonts.formats.tfm  --- “type1” -  --- fonts.readers.sequence[#fonts.readers.sequence+1] = "ofm" -  -------------------------------------------------------------------- -end - ---[[doc-- - -Now we load the modules written for \identifier{luaotfload}. - ---doc]]-- -loadmodule"font-pfb.lua"    --- new in 2.0, added 2011 -loadmodule"font-nms.lua" -loadmodule"font-clr.lua" -loadmodule"font-ltx.lua"    --- new in 2.0, added 2011 - ---[[doc-- - -We create a callback for patching fonts on the fly, to be used by other -packages. -It initially contains the empty function that we are going to override -below. - ---doc]]-- - -create_callback("luaotfload.patch_font", "simple", dummy_function) - ---[[doc-- - -This is a wrapper for the imported font loader. -As of 2013, everything it does appear to be redundand, so we won’t use -it unless somebody points out a cogent reason. -Nevertheless, it has been adapted to work with the current structure of -font data objects and will stay here for reference / until breakage is -reported. - -\emphasis{TODO} -This one also enables patching fonts. -The current fontloader apparently comes with a dedicated mechanism for -that already: enhancers. -How those work remains to be figured out. - ---doc]]-- -local define_font_wrapper = function (...) -    --- we use “tfmdata” (not “fontdata”) for consistency with the -    --- font loader -    local tfmdata = fonts.definers.read(...) -    if type(tfmdata) == "table" and tfmdata.shared then -        local metadata = tfmdata.shared.rawdata.metadata -        local mathdata = metadata.math --- do all fonts have this field? -        if mathdata then -            local mathconstants = { } --- why new hash, not modify in place? -            local units_per_em  = metadata.units_per_em -            local size          = tfmdata.size -            for k,v in next, mathdata do -                --- afaics this is alread taken care of by -                --- definers.read -                if stringfind(k, "Percent") then -                    -- keep percent values as is -                    print(k,v) -                    mathconstants[k] = v -                else -                    mathconstants[k] = v / units_per_em * size -                end -            end -            --- for \overwithdelims -            --- done by definers.read as well -            mathconstants.FractionDelimiterSize             = 1.01 * size -            --- fontloader has 2.4 × size -            mathconstants.FractionDelimiterDisplayStyleSize = 2.39 * size -            tfmdata.MathConstants = mathconstants -        end -        call_callback("luaotfload.patch_font", tfmdata) -    end -    return tfmdata -end - ---[[doc-- - -\subsection{\CONTEXT override} - -We provide a simplified version of the original font definition -callback. - ---doc]]-- - -local read_font_file = fonts.definers.read -local patch_defined_font = function (...) -    local tfmdata = read_font_file(...)-- spec -> size -> id -> tmfdata -    if type(tfmdata) == "table" then -        call_callback("luaotfload.patch_font", tfmdata) -    end -    -- inspect(table.keys(tfmdata))  -    return tfmdata -end - -caches.compilemethod = "both" - -reset_callback("define_font") - ---[[doc-- -Finally we register the callbacks ---doc]]-- - -if luaotfload.font_definer == "old"  then -  add_to_callback("define_font", -                  define_font_wrapper, -                  "luaotfload.define_font", -                  1) -elseif luaotfload.font_definer == "generic"  then -  add_to_callback("define_font", -                  generic_context.callback_define_font, -                  "luaotfload.define_font", -                  1) -elseif luaotfload.font_definer == "patch"  then -  add_to_callback("define_font", -                  patch_defined_font, -                  "luaotfload.define_font", -                  1) -end - ---[[todo-- ---- The manual promises coercion of the file: lookup if ---- the asked name is enclosed in brackets. ---- A couple things make me doubt that this is the case: ---- ----     1) there doesn’t appear to be code for these cases ----     2) the brackets remain part of the file name ----     3) we still get calls to names.resolve which ----        ignores the “lookup” field of the spec it gets ---- ---- For this reason here is some code that a) coerces ---- file: lookups in these cases and b) strips the brackets ---- from the file name. As we *still* get name: lookups even ---- though this code is active I’ll just leave it here ---- for reference, ineffective as it is. -do -    local getspecification, makespecification = -        fonts.definers.getspecification, fonts.definers.makespecification - -    local analyze = function (specification, size) -        local lookup, name, sub, method, detail = getspecification(specification or "") -        local filename = stringmatch(name, "^%[(.*)%]$") -        if filename then -            lookup   = "file"    --> coerce file: -            name     = filename  --> remove brackets -        end -        return makespecification(specification, lookup, name, sub, method, detail, size) -    end -    fonts.definers.analyze = analyze -end ---]]-- - -loadmodule"features.lua" - --- vim:tw=71:sw=4:ts=4:expandtab diff --git a/otfl-features.lua b/otfl-features.lua deleted file mode 100644 index aae0515..0000000 --- a/otfl-features.lua +++ /dev/null @@ -1,110 +0,0 @@ ---[[doc-- -Taken from the most recent branch of luaotfload. ---doc]]-- -local addotffeature       = fonts.handlers.otf.addfeature -local registerotffeature  = fonts.handlers.otf.features.register - -local everywhere = { ["*"] = { ["*"] = true } } - -local tlig = { -    { -        type      = "substitution", -        features  = everywhere, -        data      = { -            [0x0022] = 0x201D,                   -- quotedblright -            [0x0027] = 0x2019,                   -- quoteleft -            [0x0060] = 0x2018,                   -- quoteright -        }, -        flags     = { }, -    }, -    { -        type     = "ligature", -        features = everywhere, -        data     = { -            [0x2013] = {0x002D, 0x002D},         -- endash -            [0x2014] = {0x002D, 0x002D, 0x002D}, -- emdash -            [0x201C] = {0x2018, 0x2018},         -- quotedblleft -            [0x201D] = {0x2019, 0x2019},         -- quotedblright -            [0x201E] = {0x002C, 0x002C},         -- quotedblbase -            [0x00A1] = {0x0021, 0x2018},         -- exclamdown -            [0x00BF] = {0x003F, 0x2018},         -- questiondown -        }, -        flags    = { }, -    }, -    { -        type     = "ligature", -        features = everywhere, -        data     = { -            [0x201C] = {0x0060, 0x0060},         -- quotedblleft -            [0x201D] = {0x0027, 0x0027},         -- quotedblright -            [0x00A1] = {0x0021, 0x0060},         -- exclamdown -            [0x00BF] = {0x003F, 0x0060},         -- questiondown -        }, -        flags    = { }, -    }, -} - -addotffeature("tlig", tlig) -addotffeature("trep", { }) -- empty, all in tlig now -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 = { far = true, urd = true, snd = true } }, -        data     = anum_persian, -        flags    = { }, -        valid    = valid, -    }, -    { -        type     = "substitution", -features = { arab = { ["*"] = true } }, -        data     = anum_arabic, -        flags    = { }, -        valid    = valid, -    }, -} - -addotffeature("anum",anum_specification) - -registerotffeature { -    name        = 'anum', -    description = 'arabic digits', -} diff --git a/otfl-font-ltx.lua b/otfl-font-ltx.lua deleted file mode 100644 index afc8621..0000000 --- a/otfl-font-ltx.lua +++ /dev/null @@ -1,205 +0,0 @@ -if not modules then modules = { } end modules ['font-ltx'] = { -    version   = 1.001, -    comment   = "companion to luatex-*.tex", -    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", -    copyright = "PRAGMA ADE / ConTeXt Development Team", -    license   = "see context related readme files" -} ---- where have all the comments gone? - -local fonts = fonts - --- A bit of tuning for definitions. - -fonts.constructors.namemode = "specification" -- somehow latex needs this (changed name!) => will change into an overload - --- tricky: we sort of bypass the parser and directly feed all into --- the sub parser - -function fonts.definers.getspecification(str) -    return "", str, "", ":", str -end - --- the generic name parser (different from context!) - -local feature_list = { } - -local report = logs.names_report - ---- ugh TODO use lpeg instead -local function isstyle(s) -    local style  = string.lower(s):split("/") -    for _,v in next, style do -        if v == "b" then -            feature_list.style = "bold" -        elseif v == "i" then -            feature_list.style = "italic" -        elseif v == "bi" or v == "ib" then -            feature_list.style = "bolditalic" -        elseif v:find("^s=") then -            feature_list.optsize = v:split("=")[2] -        elseif v == "aat" or v == "icu" or v == "gr" then -            report("log", 0, -                "load font", "unsupported font option: %s", v) -        elseif not v:is_empty() then -            feature_list.style = v:gsub("[^%a%d]", "") -        end -    end -end - -local defaults = { -    dflt = { -        "ccmp", "locl", "rlig", "liga", "clig", -        "kern", "mark", "mkmk", 'itlc', -    }, -    arab = { -        "ccmp", "locl", "isol", "fina", "fin2", -        "fin3", "medi", "med2", "init", "rlig", -        "calt", "liga", "cswh", "mset", "curs", -        "kern", "mark", "mkmk", -    }, -    deva = { -        "ccmp", "locl", "init", "nukt", "akhn", -        "rphf", "blwf", "half", "pstf", "vatu", -        "pres", "blws", "abvs", "psts", "haln", -        "calt", "blwm", "abvm", "dist", "kern", -        "mark", "mkmk", -    }, -    khmr = { -        "ccmp", "locl", "pref", "blwf", "abvf", -        "pstf", "pres", "blws", "abvs", "psts", -        "clig", "calt", "blwm", "abvm", "dist", -        "kern", "mark", "mkmk", -    }, -    thai = { -        "ccmp", "locl", "liga", "kern", "mark", -        "mkmk", -    }, -    hang = { -        "ccmp", "ljmo", "vjmo", "tjmo", -    }, -} - -defaults.beng = defaults.deva -defaults.guru = defaults.deva -defaults.gujr = defaults.deva -defaults.orya = defaults.deva -defaults.taml = defaults.deva -defaults.telu = defaults.deva -defaults.knda = defaults.deva -defaults.mlym = defaults.deva -defaults.sinh = defaults.deva - -defaults.syrc = defaults.arab -defaults.mong = defaults.arab -defaults.nko  = defaults.arab - -defaults.tibt = defaults.khmr - -defaults.lao  = defaults.thai - -local function set_default_features(script) -    local features -    local script = script or "dflt" -    report("log", 0, "load font", -        "auto-selecting default features for script: %s", -        script) -    if defaults[script] then -        features = defaults[script] -    else -        features = defaults["dflt"] -    end -    for _,v in next, features do -        if feature_list[v] ~= false then -            feature_list[v] = true -        end -    end -end - -local function issome ()    feature_list.lookup = 'name' end -local function isfile ()    feature_list.lookup = 'file' end -local function isname ()    feature_list.lookup = 'name' end -local function thename(s)   feature_list.name   = s end -local function issub  (v)   feature_list.sub    = v end -local function istrue (s)   feature_list[s]     = true end -local function isfalse(s)   feature_list[s]     = false end -local function iskey  (k,v) feature_list[k]     = v end - -local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C - -local spaces     = P(" ")^0 ---local namespec   = (1-S("/:("))^0 -- was: (1-S("/: ("))^0 ---[[phg-- this prevents matching of absolute paths as file names --]]-- -local namespec   = (1-S("/:("))^1 -local filespec   = (R("az", "AZ") * P(":"))^-1 * (1-S(":("))^1 -local stylespec  = spaces * P("/") * (((1-P(":"))^0)/isstyle) * spaces -local filename   = (P("file:")/isfile * (filespec/thename)) + (P("[") * P(true)/isname * (((1-P("]"))^0)/thename) * P("]")) -local fontname   = (P("name:")/isname * (namespec/thename)) + P(true)/issome * (namespec/thename) -local sometext   = (R("az","AZ","09") + S("+-.,"))^1 -local truevalue  = P("+") * spaces * (sometext/istrue) -local falsevalue = P("-") * spaces * (sometext/isfalse) -local keyvalue   = P("+") + (C(sometext) * spaces * P("=") * spaces * C(sometext))/iskey -local somevalue  = sometext/istrue -local subvalue   = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim -local option     = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces -local options    = P(":") * spaces * (P(";")^0  * option)^0 -local pattern    = (filename + fontname) * subvalue^0 * stylespec^0 * options^0 - -local function colonized(specification) -- xetex mode -    feature_list = { } -    lpeg.match(pattern,specification.specification) -    set_default_features(feature_list.script) -    if feature_list.style then -        specification.style = feature_list.style -        feature_list.style = nil -    end -    if feature_list.optsize then -        specification.optsize = feature_list.optsize -        feature_list.optsize = nil -    end -    if feature_list.name then -        if resolvers.findfile(feature_list.name, "tfm") then -            feature_list.lookup = "file" -            feature_list.name   = file.addsuffix(feature_list.name, "tfm") -        elseif resolvers.findfile(feature_list.name, "ofm") then -            feature_list.lookup = "file" -            feature_list.name   = file.addsuffix(feature_list.name, "ofm") -        end - -        specification.name = feature_list.name -        feature_list.name = nil -    end -    if feature_list.lookup then -        specification.lookup = feature_list.lookup -        feature_list.lookup = nil -    end -    if feature_list.sub then -        specification.sub = feature_list.sub -        feature_list.sub = nil -    end -    if not feature_list.mode then -        -- if no mode is set, use our default -        feature_list.mode = fonts.mode -    end -    specification.features.normal = fonts.handlers.otf.features.normalize(feature_list) -    return specification -end - -fonts.definers.registersplit(":",colonized,"cryptic") -fonts.definers.registersplit("", colonized,"more cryptic") -- catches \font\text=[names] - -function fonts.definers.applypostprocessors(tfmdata) -    local postprocessors = tfmdata.postprocessors -    if postprocessors then -        for i=1,#postprocessors do -            local extrahash = postprocessors[i](tfmdata) -- after scaling etc -            if type(extrahash) == "string" and extrahash ~= "" then -                -- e.g. a reencoding needs this -                extrahash = string.gsub(lower(extrahash),"[^a-z]","-") -                tfmdata.properties.fullname = format("%s-%s",tfmdata.properties.fullname,extrahash) -            end -        end -    end -    return tfmdata -end --- vim:tw=71:sw=4:ts=4:expandtab diff --git a/otfl-font-otc.lua b/otfl-font-otc.lua deleted file mode 100644 index a87dcad..0000000 --- a/otfl-font-otc.lua +++ /dev/null @@ -1,333 +0,0 @@ -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 registerotffeature  = otf.features.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("registering feature %a, affected glyphs %a, skipped glyphs %a",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', -} diff --git a/otfl-fonts.lua b/otfl-fonts.lua deleted file mode 100644 index 96f3501..0000000 --- a/otfl-fonts.lua +++ /dev/null @@ -1,253 +0,0 @@ -if not modules then modules = { } end modules ['luatex-fonts'] = { -    version   = 1.001, -    comment   = "companion to luatex-fonts.tex", -    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL", -    copyright = "PRAGMA ADE / ConTeXt Development Team", -    license   = "see context related readme files" -} - --- The following code isolates the generic context code from already defined or to be defined --- namespaces. This is the reference loader for plain, but the generic code is also used in --- luaotfload (which is is a file meant for latex) and that used to be maintained by Khaled --- Hosny. We do our best to keep the interface as clean as possible. --- --- The code base is rather stable now, especially if you stay away from the non generic code. All --- relevant data is organized in tables within the main table of a font instance. There are a few --- places where in context other code is plugged in, but this does not affect the core code. Users --- can (given that their macro package provides this option) access the font data (characters, --- descriptions, properties, parameters, etc) of this main table. --- --- Future versions will probably have some more specific context code removed, like tracing and --- obscure hooks, so that we have a more efficient version (and less files too). So, don't depend --- too much on low level code that is meant for context as it can change without notice. - -utf = utf or unicode.utf8 - --- We have some (global) hooks (for latex): - -if not non_generic_context then -    non_generic_context = { } -end - -if not non_generic_context.luatex_fonts then -    non_generic_context.luatex_fonts = { -     -- load_before  = nil, -     -- load_after   = nil, -     -- skip_loading = nil, -    } -end - -if not generic_context then -    generic_context  = { } -end - -if not generic_context.push_namespaces then - -    function generic_context.push_namespaces() -        texio.write(" <push namespace>") -        local normalglobal = { } -        for k, v in next, _G do -            normalglobal[k] = v -        end -        return normalglobal -    end - -    function generic_context.pop_namespaces(normalglobal,isolate) -        if normalglobal then -            texio.write(" <pop namespace>") -            for k, v in next, _G do -                if not normalglobal[k] then -                    generic_context[k] = v -                    if isolate then -                        _G[k] = nil -                    end -                end -            end -            for k, v in next, normalglobal do -                _G[k] = v -            end -            -- just to be sure: -            setmetatable(generic_context,_G) -        else -            texio.write(" <fatal error: invalid pop of generic_context>") -            os.exit() -        end -    end - -end - -local whatever = generic_context.push_namespaces() - --- We keep track of load time by storing the current time. That way we cannot be accused --- of slowing down loading too much. Anyhow, there is no reason for this library to perform --- slower in any other package as it does in context. --- --- Please don't update to this version without proper testing. It might be that this version --- lags behind stock context and the only formal release takes place around tex live code --- freeze. - -local starttime = os.gettimeofday() - --- As we don't use the context file searching, we need to initialize the kpse library. As the --- progname can be anything we will temporary switch to the context namespace if needed. Just --- adding the context paths to the path specification is somewhat faster. --- --- Now, with lua 5.2 being used we might create a special ENV for this. - --- kpse.set_program_name("luatex") - -local ctxkpse = nil -local verbose = true - -local function loadmodule(name,continue) -    local foundname = kpse.find_file(name,"tex") or "" -    if not foundname then -        if not ctxkpse then -            ctxkpse = kpse.new("luatex","context") -        end -        foundname = ctxkpse:find_file(name,"tex") or "" -    end -    if foundname == "" then -        if not continue then -            texio.write_nl(string.format(" <luatex-fonts: unable to locate %s>",name)) -            os.exit() -        end -    else -        if verbose then -            texio.write(string.format(" <%s>",foundname)) -- no file.basename yet -        end -        dofile(foundname) -    end -end - -if non_generic_context.luatex_fonts.load_before then -    loadmodule(non_generic_context.luatex_fonts.load_before,true) -end - -if non_generic_context.luatex_fonts.skip_loading ~= true then - -    loadmodule('luatex-fonts-merged.lua',true) - -    if fonts then - -        if not fonts._merge_loaded_message_done_ then -            texio.write_nl("log", "!") -            texio.write_nl("log", "! I am using the merged version of 'luatex-fonts.lua' here. If") -            texio.write_nl("log", "! you run into problems or experience unexpected behaviour, and") -            texio.write_nl("log", "! if you have ConTeXt installed you can try to delete the file") -            texio.write_nl("log", "! 'luatex-font-merged.lua' as I might then use the possibly") -            texio.write_nl("log", "! updated libraries. The merged version is not supported as it") -            texio.write_nl("log", "! is a frozen instance. Problems can be reported to the ConTeXt") -            texio.write_nl("log", "! mailing list.") -            texio.write_nl("log", "!") -        end - -        fonts._merge_loaded_message_done_ = true - -    else - -        -- The following helpers are a bit overkill but I don't want to mess up context code for the -        -- sake of general generality. Around version 1.0 there will be an official api defined. -        -- -        -- So, I will strip these libraries and see what is really needed so that we don't have this -        -- overhead in the generic modules. The next section is only there for the packager, so stick -        -- to using luatex-fonts with luatex-fonts-merged.lua and forget about the rest. The following -        -- list might change without prior notice (for instance because we shuffled code around). - -        loadmodule("l-lua.lua") -        loadmodule("l-lpeg.lua") -        loadmodule("l-function.lua") -        loadmodule("l-string.lua") -        loadmodule("l-table.lua") -        loadmodule("l-io.lua") -        loadmodule("l-file.lua") -        loadmodule("l-boolean.lua") -        loadmodule("l-math.lua") -        loadmodule("util-str.lua") - -        -- The following modules contain code that is either not used at all outside context or will fail -        -- when enabled due to lack of other modules. - -        -- First we load a few helper modules. This is about the miminum needed to let the font modules do -        -- their work. Don't depend on their functions as we might strip them in future versions of his -        -- generic variant. - -        loadmodule('luatex-basics-gen.lua') -        loadmodule('data-con.lua') - -        -- We do need some basic node support. The code in there is not for general use as it might change. - -        loadmodule('luatex-basics-nod.lua') - -        -- Now come the font modules that deal with traditional tex fonts as well as open type fonts. We only -        -- support OpenType fonts here. -        -- -        -- The font database file (if used at all) must be put someplace visible for kpse and is not shared -        -- with context. The mtx-fonts script can be used to genate this file (using the --names option). - -        -- in 2013/14 we will merge/move some generic files into luatex-fonts-* files (copies) so that -        -- intermediate updates of context not interfere; we can then also use the general merger - -        loadmodule('font-ini.lua') -        loadmodule('font-con.lua') -        loadmodule('luatex-fonts-enc.lua') -- will load font-age on demand -        loadmodule('font-cid.lua') -        loadmodule('font-map.lua')         -- for loading lum file (will be stripped) -        loadmodule('luatex-fonts-syn.lua') -- deals with font names (synonyms) -        loadmodule('luatex-fonts-tfm.lua') -        loadmodule('font-oti.lua') -        loadmodule('font-otf.lua') -        loadmodule('font-otb.lua') -        loadmodule('node-inj.lua')         -- will be replaced (luatex >= .70) -        loadmodule('font-ota.lua') -        loadmodule('font-otn.lua') -        ----------('luatex-fonts-chr.lua') -        loadmodule('luatex-fonts-lua.lua') -        loadmodule('font-def.lua') -        loadmodule('luatex-fonts-def.lua') -        loadmodule('luatex-fonts-ext.lua') -- some extensions - -        -- We need to plug into a callback and the following module implements the handlers. Actual plugging -        -- in happens later. - -        loadmodule('luatex-fonts-cbk.lua') - -    end - -end - -if non_generic_context.luatex_fonts.load_after then -    loadmodule(non_generic_context.luatex_fonts.load_after,true) -end - -resolvers.loadmodule = loadmodule - --- In order to deal with the fonts we need to initialize some callbacks. One can overload them later on if --- needed. First a bit of abstraction. - -generic_context.callback_ligaturing           = false -generic_context.callback_kerning              = false -generic_context.callback_pre_linebreak_filter = nodes.simple_font_handler -generic_context.callback_hpack_filter         = nodes.simple_font_handler -generic_context.callback_define_font          = fonts.definers.read - --- The next ones can be done at a different moment if needed. You can create a generic_context namespace --- and set no_callbacks_yet to true, load this module, and enable the callbacks later. So, there is really --- *no* need to create a alternative for luatex-fonts.lua and luatex-fonts-merged.lua: just load this one --- and overload if needed. - -if not generic_context.no_callbacks_yet then - -    callback.register('ligaturing',           generic_context.callback_ligaturing) -    callback.register('kerning',              generic_context.callback_kerning) -    callback.register('pre_linebreak_filter', generic_context.callback_pre_linebreak_filter) -    callback.register('hpack_filter',         generic_context.callback_hpack_filter) -    callback.register('define_font' ,         generic_context.callback_define_font) - -end - --- We're done. - -texio.write(string.format(" <luatex-fonts.lua loaded in %0.3f seconds>", os.gettimeofday()-starttime)) - -generic_context.pop_namespaces(whatever) diff --git a/tests/lookups.tex b/tests/lookups.tex new file mode 100644 index 0000000..db26312 --- /dev/null +++ b/tests/lookups.tex @@ -0,0 +1,14 @@ +\input luaotfload.sty +%% lookup font by name (involving database) +\font\first=name:iwonaregular at 42pt +%% lookup font by file name (kpse) +\font\second=file:antpoltltsemiexpd-bolditalic.otf at 42pt +%% lookup font by name, with style in slash notation +\font\third={name:Antykwa torunska/I} at 42pt + +{\first   foo \endgraf} +{\second  bar \endgraf} +{\third   baz \endgraf} + +\bye + | 
