luaotfload = luaotfload or { } luaotfload.fonts = { } luaotfload.fonts.module = { name = "luaotfload.fonts", version = 1.001, date = "2010/01/12", description = "luaotfload font database.", author = "Khaled Hosny", copyright = "Khaled Hosny", license = "CC0" } kpse.set_program_name("luatex") require("luaextra.lua") require("otfl-luat-dum.lua") local upper, splitpath, expandpath, glob, basename = string.upper, file.split_path, kpse.expand_path, dir.glob, file.basename luaotfload.fonts.basename = "otfl-names.lua" luaotfload.fonts.version = 2.000 luaotfload.fonts.log = false local function log(...) if luaotfload.fonts.log then logs.simple(...) end end local function info(...) logs.simple(...) end local function sanitize(str) return string.gsub(string.lower(str), "[^%a%d]", "") end local function tprint(t) print(table.serialize(t)) end function fontloader.fullinfo(filename, subfont) -- info("loaing %s", filename) local f, w, m, t, n = nil, nil, nil, { }, { } if subfont then f, w = fontloader.open(filename, subfont) else f, w = fontloader.open(filename) end m = fontloader.to_table(f) fontloader.close(f) m.glyphs, m.gpos, m.gsub, m.kerns, m.lookups, m.map = nil, nil, nil, nil, nil, nil m.anchor_classes, m.mark_classes, m.horiz_base = nil, nil, nil if m.names then for _,v in pairs(m.names) do if v.lang == "English (US)" then n.fullname = v.names.compatfull n.familyname = v.names.preffamilyname n.subfamily = v.names.subfamily n.modifier = v.names.prefmodifiers end end end if m.fontstyle_name then for _,v in pairs(m.fontstyle_name) do if v.lang == 1033 then m.style = v.name end end end t.psname = m.fontname t.fullname = n.fullname or m.fullname t.family = n.familyname or m.familyname t.style = n.subfamily or m.style if not t.style or t.style:is_empty() then local s = t.psname:split("-") if s and #s >= 2 then t.style = s[#s] end end if not t.style or t.style:is_empty() then t.style = n.modifier end if not t.style or t.style:is_empty() then if n.fullname and n.familyname then t.style = (n.fullname:gsub(n.familyname, "") ~= n.fullname and n.fullname:gsub(n.familyname, "")) or nil elseif m.fontname and m.familyname then t.style = (m.fontname:gsub(m.familyname, "") ~= m.fontname and m.fontname:gsub(m.familyname, "")) or nil end end if not t.style or t.style:is_empty() then t.style = (m.fullname:gsub(m.familyname, "") ~= m.fullname and m.fullname:gsub(m.familyname, "")) or nil end if not t.style or t.style:is_empty() then t.style = "Regular" end for k,v in pairs(t) do t[k] = sanitize(v) end -- tprint(m) print(w) m, n = nil, nil return t end local function load_font(filename, names, texmf) local psnames, families = names.mappings.psnames, names.mappings.families if filename then local info = fontloader.info(filename) if info then if type(info) == "table" and #info > 1 then for index,_ in ipairs(info) do local fullinfo = fontloader.fullinfo(filename, index-1) if not families[fullinfo.family] then families[fullinfo.family] = { } end families[fullinfo.family][fullinfo.style] = {texmf and basename(filename) or filename, index-1} psnames[fullinfo.psname] = {texmf and basename(filename) or filename, index-1} end else local fullinfo = fontloader.fullinfo(filename) if texmf == true then filename = basename(filename) end if not families[fullinfo.family] then families[fullinfo.family] = { } end families[fullinfo.family][fullinfo.style] = {texmf and basename(filename) or filename} psnames[fullinfo.psname] = {texmf and basename(filename) or filename} end else log("Failed to load %s", filename) end end end local function scan_dir(dirname, names, recursive, texmf) local list, found = { }, { } for _,ext in ipairs { "otf", "ttf", "ttc", "dfont" } do if recursive then pat = "/**." else pat = "/*." end log("Scanning '%s' for '%s' fonts", dirname, ext) found = glob(dirname .. pat .. ext) log("%s fonts found", #found) table.append(list, found) log("Scanning '%s' for '%s' fonts", dirname, upper(ext)) found = glob(dirname .. pat .. upper(ext)) log("%s fonts found", #found) table.append(list, found) end for _,fnt in ipairs(list) do load_font(fnt, names, texmf) end end --[[ local function scan_os_fonts(names) local fontdirs fontdirs = expandpath("$OSFONTDIR") if not fontdirs:is_empty() then fontdirs = splitpath(fontdirs, ":") for _,d in ipairs(fontdirs) do scan_dir(d, names, true) end end end --]] local function scan_txmf_tree(names) local fontdirs = expandpath("$OPENTYPEFONTS") fontdirs = fontdirs .. expandpath("$TTFONTS") if not fontdirs:is_empty() then fontdirs = splitpath(fontdirs, ":") for _,d in ipairs(fontdirs) do scan_dir(d, names, false, true) end end end local function generate() local fnames = { mappings = { families = { }, psnames = { }, }, version = luaotfload.fonts.version } local savepath scan_txmf_tree(fnames) logs.simple("%s fonts saved in the database", #table.keys(fnames.mappings.psnames)) savepath = kpse.expand_var("$TEXMFVAR") .. "/tex/" lfs.mkdir(savepath) savepath = savepath .. luaotfload.fonts.basename io.savedata(savepath, table.serialize(fnames, true)) logs.simple("Saved font names database in %s\n", savepath) end luaotfload.fonts.scan = scan_dir luaotfload.fonts.generate = generate if arg[0] == "luaotfload-fonts.lua" then generate() -- t = fontloader.fullinfo(arg[1]) -- tprint(t) end