diff options
| author | Philipp Gesang <phg42.2a@gmail.com> | 2013-04-30 12:38:52 -0700 | 
|---|---|---|
| committer | Philipp Gesang <phg42.2a@gmail.com> | 2013-04-30 12:38:52 -0700 | 
| commit | 6028177d2a5fd2e7c9a84d48af9023e2685b6c05 (patch) | |
| tree | f6d9d3c60fa501202978e90ad22b3f3497d7702a | |
| parent | 9c515301f1fafaebe311a042ad11f9fabdecb133 (diff) | |
| parent | 700de901361c164652762b0c31b730792ace18d0 (diff) | |
| download | luaotfload-6028177d2a5fd2e7c9a84d48af9023e2685b6c05.tar.gz | |
Merge pull request #25 from phi-gamma/master
close issue #20
| -rw-r--r-- | luaotfload-database.lua | 116 | ||||
| -rw-r--r-- | luaotfload.dtx | 96 | 
2 files changed, 89 insertions, 123 deletions
| diff --git a/luaotfload-database.lua b/luaotfload-database.lua index 529cdf3..f78cc67 100644 --- a/luaotfload-database.lua +++ b/luaotfload-database.lua @@ -71,12 +71,15 @@ fonts.definers       = fonts.definers or { }  local names          = fonts.names -names.version        = 2.202 -names.data           = nil +names.version        = 2.203 +names.data           = nil      --- contains the loaded database +names.lookups        = nil      --- contains the lookup cache  names.path           = { -    basename = "luaotfload-names.lua", -    dir      = "", -    path     = "", +    dir              = "",                      --- db and cache directory +    basename         = "luaotfload-names.lua",  --- db file name +    path             = "",                      --- full path to db file +    lookup_basename  = "luaotfload-lookup-cache.lua", --- cache file name +    lookup_path      = "",                            --- cache full path  }  config                         = config or { } @@ -97,8 +100,9 @@ if caches then      if not writable_path then          error("Impossible to find a suitable writeable cache...")      end -    names.path.dir   = writable_path -    names.path.path  = filejoin(writable_path, names.path.basename) +    names.path.dir          = writable_path +    names.path.path         = filejoin(writable_path, names.path.basename) +    names.path.lookup_path  = filejoin(writable_path, names.path.lookup_basename)  else --- running as script, inject some dummies      caches = { }      logs   = { report = function () end } @@ -188,12 +192,6 @@ mtx-fonts has in names.tma:  --doc]]--  local fontnames_init = function (keep_cache) --- returns dbobj -    local request_cache -    if keep_cache and names.data and names.data.request_cache then -        request_cache = names.data.request_cache -    else -        request_cache = { } -    end      return {          mappings        = { },          status          = { }, @@ -206,7 +204,6 @@ local fontnames_init = function (keep_cache) --- returns dbobj          basenames       = { },  --      fullnames       = { },          version         = names.version, -        request_cache   = request_cache,      }  end @@ -250,11 +247,13 @@ local find_closest  local flush_cache  local font_fullinfo  local load_names +local load_lookups  local read_fonts_conf  local reload_db  local resolve  local resolve_cached  local save_names +local save_lookups  local scan_external_dir  local update_names @@ -283,6 +282,20 @@ load_names = function ( )      return data  end +--- unit -> dbobj +load_lookups = function ( ) +    local foundname, data = load_lua_file(names.path.lookup_path) +    if data then +        report("both", 1, "cache", +               "Lookup cache loaded (%s)", foundname) +    else +        report("both", 1, "cache", +               "No lookup cache, creating empty.") +        data = { } +    end +    return data +end +  local fuzzy_limit = 1 --- display closest only  local style_synonyms = { set = { } } @@ -428,20 +441,20 @@ resolver, lest we want to worry if we caught all the details.  --- 'a -> 'a -> table -> (string * int|boolean * boolean)  resolve_cached = function (_, _, specification) -    if not names.data then names.data = load_names() end -    local request_cache = names.data.request_cache +    --if not names.data then names.data = load_names() end +    if not names.lookups then names.lookups = load_lookups() end      local request = specification.specification -    report("log", 4, "cache", "looking for “%s” in cache ...", +    report("both", 4, "cache", "looking for “%s” in cache ...",             request) -    local found = names.data.request_cache[request] +    local found = names.lookups[request]      --- case 1) cache positive ----------------------------------------      if found then --- replay fields from cache hit          report("info", 4, "cache", "found!")          return found[1], found[2], true      end -    report("log", 4, "cache", "not cached; resolving") +    report("both", 4, "cache", "not cached; resolving")      --- case 2) cache negative ----------------------------------------      --- first we resolve normally ... @@ -449,8 +462,8 @@ resolve_cached = function (_, _, specification)      if not success then return filename, subfont, false end      --- ... then we add the fields to the cache ... ...      local entry = { filename, subfont } -    report("log", 4, "cache", "new entry: %s", request) -    names.data.request_cache[request] = entry +    report("both", 4, "cache", "new entry: %s", request) +    names.lookups[request] = entry      --- obviously, the updated cache needs to be stored.      --- for the moment, we write the entire db to disk @@ -459,8 +472,8 @@ resolve_cached = function (_, _, specification)      ---      document is compiled (finish_pdffile callback?)      --- TODO we should speed up writing by separating      ---      the cache from the db -    report("log", 5, "cache", "saving updated cache") -    save_names() +    report("both", 5, "cache", "saving updated cache") +    save_lookups()      return filename, subfont, true  end @@ -468,9 +481,10 @@ end  Luatex-fonts, the font-loader package luaotfload imports, comes with  basic file location facilities (see luatex-fonts-syn.lua). -However, the builtin functionality is too limited to be of more than -basic use, which is why we supply our own resolver that accesses the -font database created by the mkluatexfontdb script. +However, not only does the builtin functionality rely on Context’s font +name database, it is also too limited to be of more than basic use. +For this reason, luaotfload supplies its own resolvers that accesses +the font database created by the luaotfload-tool script.  --doc]]-- @@ -684,7 +698,7 @@ end --- resolve()  reload_db = function (why, caller, ...)      report("both", 1, "db", "reload initiated; reason: “%s”", why)      names.data = update_names() -    save_names(names.data) +    save_names()      fonts_reloaded = true      return caller(...)  end @@ -1389,10 +1403,10 @@ local function scan_os_fonts(fontnames, newfontnames)  end  flush_cache = function () -    if not names.data then names.data = load_names() end -    names.data.request_cache = { } +    if not names.lookups then names.lookups = load_lookups() end +    names.lookups = { }      collectgarbage"collect" -    return true, names.data +    return true, names.lookups  end  --- dbobj -> bool -> dbobj @@ -1448,13 +1462,47 @@ update_names = function (fontnames, force)      return newfontnames  end +--- unit -> string +local ensure_names_path = function ( ) +    local path = names.path.dir +    if not lfsisdir(path) then +        dirmkdirs(path) +    end +    return path +end + +--- The lookup cache is an experimental feature of version 2.2; +--- instead of incorporating it into the database it gets its own +--- file. As we update it after every single addition this saves us +--- quite some time. + +--- unit -> string +save_lookups = function ( ) +    ---- this is boilerplate and should be refactored into something +    ---- usable by both the db and the cache writers +    local lookups  = names.lookups +    local path     = ensure_names_path() +    if fileiswritable(path) then +        local luaname, lucname = make_name(names.path.lookup_path) +        if luaname then +            tabletofile(luaname, lookups, true) +            if lucname and type(caches.compile) == "function" then +                os.remove(lucname) +                caches.compile(lookups, luaname, lucname) +                report("info", 1, "cache", "Lookup cache saved") +                return names.path.lookup_path +            end +        end +    end +    report("info", 0, "cache", "Could not write lookup cache") +    return nil +end + +--- save_names() is usually called without the argument  --- dbobj -> unit  save_names = function (fontnames)      if not fontnames then fontnames = names.data end -    local path  = names.path.dir -    if not lfs.isdir(path) then -        dirmkdirs(path) -    end +    local path  = ensure_names_path()      if fileiswritable(path) then          local luaname, lucname = make_name(names.path.path)          if luaname then diff --git a/luaotfload.dtx b/luaotfload.dtx index e18c205..8f7c8a1 100644 --- a/luaotfload.dtx +++ b/luaotfload.dtx @@ -835,7 +835,7 @@ and the derived files  % The complete list is is given in table \ref{table-searchpaths}.  % Other paths can be specified by setting the environment variable  % \verb+OSFONTDIR+. -% If it is non-empty, then search will be limited to the included +% If it is non-empty, then search will be extended to the included  % directories.  %  % \begin{table}[t] @@ -900,7 +900,7 @@ and the derived files  % using the \verb|-i| option (\verb|--info|).  % \begin{quote}  %   \begin{verbatim} -%     luaotfload-tool  -F --find="Iwona Light Italic" +%     luaotfload-tool  -i --find="Iwona Light Italic"  %   \end{verbatim}  % \end{quote}  % \noindent @@ -1181,6 +1181,7 @@ local luaotfload            = luaotfload  config                      = config or { }  config.luaotfload           = config.luaotfload or { }  config.luaotfload.resolver  = config.luaotfload.resolver or "normal" +config.luaotfload.definer   = config.luaotfload.definer  or "patch"  --luaotfload.prefer_merge     = config.luaotfload.prefer_merge or true  luaotfload.module = { @@ -1642,54 +1643,6 @@ end  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. -% -%    \begin{macrocode} -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 - -%    \end{macrocode}  % \subsection{\CONTEXT override}  % We provide a simplified version of the original font definition  % callback. @@ -1716,55 +1669,20 @@ reset_callback("define_font")  %  %    \begin{macrocode} -if luaotfload.font_definer == "old"  then -  add_to_callback("define_font", -                  define_font_wrapper, -                  "luaotfload.define_font", -                  1) -elseif luaotfload.font_definer == "generic"  then +local font_definer = config.luaotfload.definer + +if font_definer == "generic"  then    add_to_callback("define_font",                    fonts.definers.read,                    "luaotfload.define_font",                    1) -elseif luaotfload.font_definer == "patch"  then +elseif 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" --- contains what was “font-ltx” and “font-otc”  -- vim:tw=71:sw=4:ts=4:expandtab | 
