diff options
Diffstat (limited to 'src/luaotfload-database.lua')
-rw-r--r-- | src/luaotfload-database.lua | 461 |
1 files changed, 222 insertions, 239 deletions
diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua index 437091f..7495ff2 100644 --- a/src/luaotfload-database.lua +++ b/src/luaotfload-database.lua @@ -132,11 +132,6 @@ local fontshandlers = fonts.handlers or { } local otfhandler = fonts.handlers.otf or { } fonts.handlers = fontshandlers -local read_font_file = otfhandler.readers.loadfont -local read_font_info = read_font_file -local close_font_file = function () end -local get_english_names - local gzipload = gzip.load local gzipsave = gzip.save local iolines = io.lines @@ -207,8 +202,7 @@ local make_luanames = function (path) end local format_precedence = { - "otf", "ttc", "ttf", "afm", - -- "pfb" --- may come back before Luatex 1.0 + "otf", "ttc", "ttf", "afm", "pfb" } local location_precedence = { @@ -355,25 +349,25 @@ This is a sketch of the luaotfload db: full : (int, string) hash; // idx -> full path } and fontentry = { // finalized by collect_families() - basename : string; // file name without path "foo.otf" - conflicts : { barename : int; basename : int }; // filename conflict with font at index; happens with subfonts - familyname : string; // sanitized name of the font family the font belongs to, usually from the names table - fontname : string; // sanitized name of the font - format : string; // "otf" | "ttf" | "afm" (* | "pfb" *) - fullname : string; // sanitized full name of the font including style modifiers - fullpath : string; // path to font in filesystem - index : int; // index in the mappings table - italicangle : float; // italic angle; non-zero with oblique faces - location : string; // "texmf" | "system" | "local" - metafamily : string; // alternative family identifier if appropriate, sanitized - plainname : string; // unsanitized font name - prefmodifiers : string; // sanitized preferred subfamily (names table 14) - psname : string; // PostScript name - size : (false | float * float * float); // if available, size info from the size table converted from decipoints - subfamily : string; // sanitized subfamily (names table 2) - subfont : (int | bool); // integer if font is part of a TrueType collection ("ttc") - version : string; // font version string - weight : int; // usWeightClass + basename : string; // file name without path "foo.otf" + conflicts : { barename : int; basename : int }; // filename conflict with font at index; happens with subfonts + familyname : string; // sanitized name of the font family the font belongs to, usually from the names table + fontname : string; // sanitized name of the font + format : string; // "otf" | "ttf" | "afm" (* | "pfb" *) + fullname : string; // sanitized full name of the font including style modifiers + fullpath : string; // path to font in filesystem + index : int; // index in the mappings table + italicangle : float; // italic angle; non-zero with oblique faces + location : string; // "texmf" | "system" | "local" + metafamily : string; // alternative family identifier if appropriate, sanitized + plainname : string; // unsanitized font name + typographicsubfamily : string; // sanitized preferred subfamily (names table 14) + psname : string; // PostScript name + size : (false | float * float * float); // if available, size info from the size table converted from decipoints + subfamily : string; // sanitized subfamily (names table 2) + subfont : (int | bool); // integer if font is part of a TrueType collection ("ttc") + version : string; // font version string + weight : int; // usWeightClass } and filestatus = (string, // fullname { index : int list; // pointer into mappings @@ -1016,7 +1010,7 @@ local lookup_fontname = function (specification, name, style) style = style_category [style] for i = 1, #mappings do local face = mappings [i] - local prefmodifiers = face.prefmodifiers + local typographicsubfamily = face.typographicsubfamily local subfamily = face.subfamily if face.fontname == name or face.fullname == name @@ -1024,17 +1018,17 @@ local lookup_fontname = function (specification, name, style) then return face.basename, face.subfont elseif face.familyname == name then - if prefmodifiers == style + if typographicsubfamily == style or subfamily == style then fallback = face - elseif regular_synonym [prefmodifiers] + elseif regular_synonym [typographicsubfamily] or regular_synonym [subfamily] then lastresort = face end elseif face.metafamily == name - and ( regular_synonym [prefmodifiers] + and ( regular_synonym [typographicsubfamily] or regular_synonym [subfamily]) then lastresort = face @@ -1082,12 +1076,12 @@ end size should that be? Xetex appears to pick the “normal” (unmarked) size: with Adobe fonts this would be the one that is neither “caption” nor “subhead” nor “display” &c ... For fonts by Adobe this - seems to be the one that does not receive a “prefmodifiers” field. - (IOW Adobe uses the “prefmodifiers” field to encode the design size - in more or less human readable format.) However, this is not true - of LM and EB Garamond. As this matters only where there are - multiple design sizes to a given font/style combination, we put a - workaround in place that chooses that unmarked version. + seems to be the one that does not receive a “typographicsubfamily” + field. (IOW Adobe uses the “typographicsubfamily” field to encode + the design size in more or less human readable format.) However, + this is not true of LM and EB Garamond. As this matters only where + there are multiple design sizes to a given font/style combination, + we put a workaround in place that chooses that unmarked version. The first return value of “lookup_font_name” is the file name of the requested font (string). It can be passed to the fullname resolver @@ -1304,13 +1298,29 @@ find_closest = function (name, limit) return false end --- find_closest() +--- string -> uint -> bool * (string | rawdata) +local read_font_file = function (filename, subfont) + local fontdata = otfhandler.readers.getinfo (filename, + { subfont = subfont + , details = false + , platformnames = true + , rawfamilynames = true + }) + local msg = fontdata.comment + if msg then + return false, msg + end + return true, fontdata +end + local load_font_file = function (filename, subfont) - local rawfont, _msg = read_font_file (filename, subfont, true) - if not rawfont then - logreport ("log", 1, "db", "ERROR: failed to open %s.", filename) + local err, ret = read_font_file (filename, subfont) + if err == false then + logreport ("both", 1, "db", "ERROR: failed to open %q: %q.", + tostring (filename), tostring (ret)) return end - return rawfont + return ret end --- rawdata -> (int * int * int | bool) @@ -1337,46 +1347,13 @@ local get_size_info = function (rawinfo) end --[[doc-- - get_english_names_from_ff -- For legacy Fontforge-style names - tables. Extracted from the actual names table, not the font item - itself. ---doc]]-- - -local get_english_names_from_ff = function (metadata) - local names = metadata.names - if names then - for _, raw_namedata in next, names do - if raw_namedata.lang == "English (US)" then - return raw_namedata.names - end - end - end - - -- no (English) names table, probably a broken font - logreport ("both", 3, "db", - "%s: missing or broken English names table.", basename) - return { fontname = metadata.fontname, - fullname = metadata.fullname, } -end - ---[[doc-- map_enlish_names -- Names-table for Lua fontloader objects. This may vanish eventually once we ditch Fontforge completely. Only subset of entries of that table are actually relevant so we’ll stick to that part. --doc]]-- -local names_items = { - compatfull = "compatiblefullname", - fullname = "fullname", - postscriptname = "postscriptname", - preffamily = "typographicfamily", - prefmodifiers = "typographicsubfamily", - family = "family", - subfamily = "subfamily", -} - -local map_english_names = function (metadata) +local get_english_names = function (metadata) local namesource local platformnames = metadata.platformnames --[[-- @@ -1412,16 +1389,9 @@ local map_english_names = function (metadata) --namesource = platformnames.macintosh or platformnames.windows namesource = platformnames.windows or platformnames.macintosh end - namesource = namesource or metadata - local nameinfo = { } - for ours, theirs in next, names_items do - nameinfo [ours] = namesource [theirs] - end - return nameinfo + return namesource or metadata end -get_english_names = map_english_names - --[[-- In case of broken PS names we set some dummies. @@ -1432,14 +1402,15 @@ local get_raw_info = function (metadata, basename) local fontname = metadata.fontname local fullname = metadata.fullname - local validation_state = metadata.validation_state if not fontname or not fullname then --- Broken names table, e.g. avkv.ttf with UTF-16 strings; --- we put some dummies in place like the fontloader --- (font-otf.lua) does. logreport ("both", 3, "db", - "invalid names table of font %s, using dummies.", - basename) + "Invalid names table of font %s, using dummies. \z + Reported: fontname=%q, fullname=%q.", + tostring (basename), tostring (fontname), + tostring (fullname)) fontname = "bad-fontname-" .. basename fullname = "bad-fullname-" .. basename end @@ -1462,46 +1433,46 @@ local organize_namedata = function (rawinfo, nametable, basename, info) - local default_name = nametable.compatfull + local default_name = nametable.compatiblefullname or nametable.fullname or nametable.postscriptname or rawinfo.fullname or rawinfo.fontname or info.fullname or info.fontname - local default_family = nametable.preffamily + local default_family = nametable.typographicfamily or nametable.family or rawinfo.familyname or info.familyname --- local default_modifier = nametable.prefmodifiers +-- local default_modifier = nametable.typographicsubfamily -- or nametable.subfamily local fontnames = { --- see --- https://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html --- http://www.microsoft.com/typography/OTSPEC/name.htm#NameIDs english = { - --- where a “compatfull” field is given, the value of “fullname” is - --- either identical or differs by separating the style - --- with a hyphen and omitting spaces. (According to the - --- spec, “compatfull” is “Macintosh only”.) - --- Of the three “fullname” fields, this one appears to be the one - --- with the entire name given in a legible, - --- non-abbreviated fashion, for most fonts at any rate. - --- However, in some fonts (e.g. CMU) all three fields are - --- identical. - fullname = --[[ 18 ]] nametable.compatfull + --- where a “compatiblefullname” field is given, the value + --- of “fullname” is either identical or differs by + --- separating the style with a hyphen and omitting spaces. + --- (According to the spec, “compatiblefullname” is + --- “Macintosh only”.) Of the three “fullname” fields, this + --- one appears to be the one with the entire name given in + --- a legible, non-abbreviated fashion, for most fonts at + --- any rate. However, in some fonts (e.g. CMU) all three + --- fields are identical. + fullname = --[[ 18 ]] nametable.compatiblefullname or --[[ 4 ]] nametable.fullname or default_name, --- we keep both the “preferred family” and the “family” --- values around since both are valid but can turn out --- quite differently, e.g. with Latin Modern: - --- preffamily: “Latin Modern Sans”, + --- typographicfamily: “Latin Modern Sans”, --- family: “LM Sans 10” - preffamily = --[[ 16 ]] nametable.preffamilyname, - family = --[[ 1 ]] nametable.family or default_family, - prefmodifiers = --[[ 17 ]] nametable.prefmodifiers, - subfamily = --[[ 2 ]] nametable.subfamily or rawinfo.subfamilyname, - psname = --[[ 6 ]] nametable.postscriptname, + family = --[[ 1 ]] nametable.family or default_family, + subfamily = --[[ 2 ]] nametable.subfamily or rawinfo.subfamilyname, + psname = --[[ 6 ]] nametable.postscriptname, + typographicfamily = --[[ 16 ]] nametable.typographicfamily, + typographicsubfamily = --[[ 17 ]] nametable.typographicsubfamily, }, metadata = { @@ -1596,7 +1567,6 @@ ot_fullinfo = function (filename, style = style, version = rawinfo.version, } - close_font_file (metadata) --> FF only return res end @@ -1623,12 +1593,12 @@ t1_fullinfo = function (filename, _subfont, location, basename, format) local weight sanitized = sanitize_fontnames ({ - fontname = fontname, - psname = fullname, - metafamily = familyname, - familyname = familyname, - weight = metadata.weight, --- string identifier - prefmodifiers = style, + fontname = fontname, + psname = fullname, + metafamily = familyname, + familyname = familyname, + weight = metadata.weight, --- string identifier + typographicsubfamily = style, }) weight = sanitized.weight @@ -1642,21 +1612,21 @@ t1_fullinfo = function (filename, _subfont, location, basename, format) end return { - basename = basename, - fullpath = filename, - subfont = false, - location = location or "system", - format = format, - fullname = sanitized.fullname, - fontname = sanitized.fontname, - familyname = sanitized.familyname, - plainname = fullname, - psname = sanitized.fontname, - version = metadata.version, - size = false, - prefmodifiers = style ~= "" and style or weight, - weight = metadata.pfminfo and pfminfo.weight or 400, - italicangle = italicangle, + basename = basename, + fullpath = filename, + subfont = false, + location = location or "system", + format = format, + fullname = sanitized.fullname, + fontname = sanitized.fontname, + familyname = sanitized.familyname, + plainname = fullname, + psname = sanitized.fontname, + version = metadata.version, + size = false, + typographicsubfamily = style ~= "" and style or weight, + weight = metadata.pfminfo and pfminfo.weight or 400, + italicangle = italicangle, } end @@ -1664,7 +1634,8 @@ local loaders = { otf = ot_fullinfo, ttc = ot_fullinfo, ttf = ot_fullinfo, ---- pfb = t1_fullinfo, + afm = t1_fullinfo, + pfb = t1_fullinfo, } --- not side-effect free! @@ -1808,11 +1779,12 @@ local read_font_names = function (fullname, --- 4) get basic info, abort if fontloader can’t read it - local info = read_font_file (fullname) + local err, info = read_font_file (fullname) - if not info then + if err == false then logreport ("log", 1, "db", - "Failed to read basic information from %q", basename) + "Failed to read basic information from %q: %q", + basename, tostring (info)) return false end @@ -2057,8 +2029,18 @@ do end end +local locate_matching_pfb = function (afmfile, dir) + local pfbname = filereplacesuffix (afmfile, "pfb") + local pfbpath = dir .. "/" .. pfbname + if lfsisfile (pfbpath) then + return pfbpath + end + --- Check for match in texmf too + return kpsefind_file (pfbname, "type1 fonts") +end + local process_dir_tree -process_dir_tree = function (acc, dirs) +process_dir_tree = function (acc, dirs, done) if not next (dirs) then --- done return acc end @@ -2067,48 +2049,56 @@ process_dir_tree = function (acc, dirs) local dir = dirs[#dirs] dirs[#dirs] = nil - if lfschdir (dir) then - lfschdir (pwd) - - local newfiles = { } - local blacklist = names.blacklist - for ent in lfsdir (dir) do - --- filter right away - if ent ~= "." and ent ~= ".." and not blacklist[ent] then - local fullpath = dir .. "/" .. ent - if lfsisdir (fullpath) - and not lpegmatch (p_blacklist, fullpath) - then - dirs[#dirs+1] = fullpath - elseif lfsisfile (fullpath) then - ent = stringlower (ent) - - if lpegmatch (p_font_filter, ent) then - if filesuffix (ent) == "afm" then - --- fontloader.open() will load the afm - --- iff both files are in the same directory - local pfbpath = filereplacesuffix - (fullpath, "pfb") - if lfsisfile (pfbpath) then - newfiles[#newfiles+1] = pfbpath - end - else - newfiles[#newfiles+1] = fullpath + if not lfschdir (dir) then + --- Cannot cd; skip. + return process_dir_tree (acc, dirs, done) + end + + dir = lfscurrentdir () --- resolve symlinks + lfschdir (pwd) + if tablecontains (done, dir) then + --- Already traversed. Note that it’d be unsafe to rely on the + --- hash part above due to Lua only processing up to 32 bytes + --- of string data. The lookup shouldn’t impact performance too + --- much but we could check the performance of alternative data + --- structures at some point. + return process_dir_tree (acc, dirs, done) + end + + local newfiles = { } + local blacklist = names.blacklist + for ent in lfsdir (dir) do + --- filter right away + if ent ~= "." and ent ~= ".." and not blacklist[ent] then + local fullpath = dir .. "/" .. ent + if lfsisdir (fullpath) + and not lpegmatch (p_blacklist, fullpath) + then + dirs[#dirs+1] = fullpath + elseif lfsisfile (fullpath) then + ent = stringlower (ent) + if lpegmatch (p_font_filter, ent) then + newfiles[#newfiles+1] = fullpath + if filesuffix (ent) == "afm" then + local pfbpath = locate_matching_pfb (ent, dir) + if pfbpath then + newfiles[#newfiles+1] = pfbpath end + else + newfiles[#newfiles+1] = fullpath end - end end end - return process_dir_tree (tableappend (acc, newfiles), dirs) end - --- cannot cd; skip - return process_dir_tree (acc, dirs) + done [#done + 1] = dir + return process_dir_tree (tableappend (acc, newfiles), dirs, done) end local process_dir = function (dir) local pwd = lfscurrentdir () if lfschdir (dir) then + dir = lfscurrentdir () --- resolve symlinks lfschdir (pwd) local files = { } @@ -2121,12 +2111,8 @@ local process_dir = function (dir) if lpegmatch (p_font_filter, ent) then if filesuffix (ent) == "afm" then - --- fontloader.open() will load the afm - --- iff both files are in the same - --- directory - local pfbpath = filereplacesuffix - (fullpath, "pfb") - if lfsisfile (pfbpath) then + local pfbpath = locate_matching_pfb (ent, dir) + if pfbpath then files[#files+1] = pfbpath end else @@ -2145,7 +2131,7 @@ end local find_font_files = function (root, recurse) if lfsisdir (root) then if recurse == true then - return process_dir_tree ({}, { root }) + return process_dir_tree ({}, { root }, {}) else --- kpathsea already delivered the necessary subdirs return process_dir (root) end @@ -2261,6 +2247,7 @@ local collect_font_filenames_texmf = function () fontdirs = kpseexpand_path "$OPENTYPEFONTS" fontdirs = fontdirs .. path_separator .. kpseexpand_path "$TTFONTS" fontdirs = fontdirs .. path_separator .. kpseexpand_path "$T1FONTS" + fontdirs = fontdirs .. path_separator .. kpseexpand_path "$AFMFONTS" if stringis_empty (fontdirs) then return { } @@ -2568,6 +2555,7 @@ end local bold_spectrum_low = 501 --- 500 is medium, 900 heavy/black local bold_weight = 700 +local normal_width = 5 local pick_style local pick_fallback_style @@ -2596,18 +2584,19 @@ do return false end - pick_style = function (prefmodifiers, - subfamily) + pick_style = function (typographicsubfamily, subfamily) local style - if prefmodifiers then - style = choose_exact (prefmodifiers) + if typographicsubfamily then + style = choose_exact (typographicsubfamily) + if style then return style end elseif subfamily then style = choose_exact (subfamily) + if style then return style end end - return style + return false end - pick_fallback_style = function (italicangle, weight, pfmweight) + pick_fallback_style = function (italicangle, pfmweight, width) --[[-- More aggressive, but only to determine bold faces. Note: Before you make this test more inclusive, ensure @@ -2618,7 +2607,8 @@ do treating weights > 500 as bold or allowing synonyms like “heavy”, “black”. --]]-- - if pfmweight == bold_weight then --- bold spectrum matches + if width == normal_width and pfmweight == bold_weight then + --- bold spectrum matches if italicangle == 0 then return "b" end @@ -2630,30 +2620,46 @@ do --- we use only exact matches here since there are constructs --- like “regularitalic” (Cabin, Bodoni Old Fashion) - check_regular = function (prefmodifiers, + check_regular = function (typographicsubfamily, subfamily, italicangle, weight, + width, pfmweight) local plausible_weight = false --[[-- This filters out undesirable candidates that specify their - prefmodifiers or subfamily as “regular” but are actually of + typographicsubfamily or subfamily as “regular” but are actually of “semibold” or other weight—another drawback of the oversimplifying classification into only three styles (r, i, b, bi). --]]-- - if italicangle == 0 then - if pfmweight == 400 then plausible_weight = true - elseif weight and regular_synonym [weight] then plausible_weight = true end + if pfmweight == 400 then + --[[-- + Some fonts like Dejavu advertise an undistinguished + regular and a “condensed” version with the same + weight whilst also providing the style info in the + typographic subfamily instead of the subfamily (i. e. + the converse of what Adobe’s doing). The only way to + weed out the undesired pseudo-regular shape is to + peek at its advertised width (4 vs. 5). + --]]-- + if width then + plausible_weight = width == normal_width + else + plausible_weight = true + end + elseif weight and regular_synonym [weight] then + plausible_weight = true + end end if plausible_weight then - if prefmodifiers and regular_synonym [prefmodifiers] - or subfamily and regular_synonym [subfamily] - then - return "r" + if subfamily then + if regular_synonym [subfamily] then return "r" end + elseif typographicsubfamily then + if regular_synonym [typographicsubfamily] then return "r" end end end return false @@ -2676,18 +2682,19 @@ local pull_values = function (entry) entry.subfont = file.subfont --- pull name info ... - entry.psname = english.psname - entry.fontname = info.fontname or metadata.fontname - entry.fullname = english.fullname or info.fullname - entry.prefmodifiers = english.prefmodifiers - entry.familyname = metadata.familyname or english.preffamily or english.family - entry.plainname = names.fullname - entry.subfamily = english.subfamily + entry.psname = english.psname + entry.fontname = info.fontname or metadata.fontname + entry.fullname = english.fullname or info.fullname + entry.typographicsubfamily = english.typographicsubfamily + entry.familyname = metadata.familyname or english.typographicfamily or english.family + entry.plainname = names.fullname + entry.subfamily = english.subfamily --- pull style info ... entry.italicangle = style.italicangle entry.size = style.size entry.weight = style.weight + entry.width = style.width entry.pfmweight = style.pfmweight if config.luaotfload.db.strip == true then @@ -2742,28 +2749,27 @@ local collect_families = function (mappings) pull_values (entry) end - local subtable = get_subtable (families, entry) - - local familyname = entry.familyname - local prefmodifiers = entry.prefmodifiers - local subfamily = entry.subfamily - - local weight = entry.weight - local pfmweight = entry.pfmweight - local italicangle = entry.italicangle - - local modifier = pick_style (prefmodifiers, subfamily) + local subtable = get_subtable (families, entry) + local familyname = entry.familyname + local typographicsubfamily = entry.typographicsubfamily + local subfamily = entry.subfamily + local weight = entry.weight + local width = entry.width + local pfmweight = entry.pfmweight + local italicangle = entry.italicangle + local modifier = pick_style (typographicsubfamily, subfamily) if not modifier then --- regular, exact only - modifier = check_regular (prefmodifiers, + modifier = check_regular (typographicsubfamily, subfamily, italicangle, weight, + width, pfmweight) end if not modifier then - modifier = pick_fallback_style (italicangle, weight, pfmweight) + modifier = pick_fallback_style (italicangle, pfmweight, width) end if modifier then @@ -2994,7 +3000,7 @@ local collect_statistics = function (mappings) local sum_dsnsize, n_dsnsize = 0, 0 local fullname, family, families = { }, { }, { } - local subfamily, prefmodifiers = { }, { } + local subfamily, typographicsubfamily = { }, { } local addtohash = function (hash, item) if item then @@ -3050,10 +3056,10 @@ local collect_statistics = function (mappings) local names = entry.names.sanitized local englishnames = names.english - addtohash (fullname, englishnames.fullname) - addtohash (family, englishnames.family) - addtohash (subfamily, englishnames.subfamily) - addtohash (prefmodifiers, englishnames.prefmodifiers) + addtohash (fullname, englishnames.fullname) + addtohash (family, englishnames.family) + addtohash (subfamily, englishnames.subfamily) + addtohash (typographicsubfamily, englishnames.typographicsubfamily) addtoset (families, englishnames.family, englishnames.fullname) @@ -3124,9 +3130,9 @@ local collect_statistics = function (mappings) pprint_top (subfamily, 4) logreport ("both", 0, "db", - " · %d different “prefmodifiers” kinds.", - setsize (prefmodifiers)) - pprint_top (prefmodifiers, 4) + " · %d different “typographicsubfamily” kinds.", + setsize (typographicsubfamily)) + pprint_top (typographicsubfamily, 4) end @@ -3143,7 +3149,7 @@ local collect_statistics = function (mappings) }, -- style = { -- subfamily = subfamily, --- prefmodifiers = prefmodifiers, +-- typographicsubfamily = typographicsubfamily, -- }, } end @@ -3500,29 +3506,6 @@ local show_cache = function ( ) return true end -local use_fontforge = function (val) - if val == true then - local fontloader = fontloader - read_font_info = fontloader.info - read_font_file = fontloader.open - close_font_file = fontloader.close - get_english_names = get_english_names_from_ff - else - local wrapper = function (filename, subfont) - return otfhandler.readers.getinfo (filename, - { subfont = subfont - , details = false - , platformnames = true - , rawfamilynames = true - }) - end - read_font_file = wrapper - read_font_info = wrapper - close_font_file = function () end - get_english_names = map_english_names - end -end - ----------------------------------------------------------------------- --- export functionality to the namespace “fonts.names” ----------------------------------------------------------------------- @@ -3554,7 +3537,7 @@ local export = { show_cache = show_cache, find_closest = find_closest, --- transitionary - use_fontforge = use_fontforge, + use_fontforge = false, } return { @@ -3570,7 +3553,7 @@ return { fonts.definers = fonts.definers or { resolvers = { } } names.blacklist = blacklist - names.version = 2.7 + names.version = 2.8 names.data = nil --- contains the loaded database names.lookups = nil --- contains the lookup cache |