summaryrefslogtreecommitdiff
path: root/luaotfload-database.lua
diff options
context:
space:
mode:
Diffstat (limited to 'luaotfload-database.lua')
-rw-r--r--luaotfload-database.lua193
1 files changed, 114 insertions, 79 deletions
diff --git a/luaotfload-database.lua b/luaotfload-database.lua
index 2741ab0..50f3e08 100644
--- a/luaotfload-database.lua
+++ b/luaotfload-database.lua
@@ -18,6 +18,7 @@ local pcall = pcall
local require = require
local tonumber = tonumber
+local fontloaderinfo = fontloader.info
local iolines = io.lines
local ioopen = io.open
local kpseexpand_path = kpse.expand_path
@@ -156,7 +157,7 @@ local fontnames_init = function ( )
return {
mappings = { },
status = { },
- filenames = { }, --- maybe overkill
+ filenames = { }, --- (basename, fullname) hash; maybe overkill
version = names.version,
}
end
@@ -626,78 +627,95 @@ font_fullinfo = function (filename, subfont, texmf)
return tfmdata
end
------ load_font(file, fontnames, newfontnames, texmf)
-local load_font = function (filename, fontnames, newfontnames, texmf)
- local newmappings = newfontnames.mappings
- local newstatus = newfontnames.status
- local mappings = fontnames.mappings
- local status = fontnames.status
- local basename = filebasename(filename)
- local basefile = texmf and basename or filename
- if filename then
- if names.blacklist[filename] or
- names.blacklist[basename] then
- report("log", 2, "db", "ignoring blacklisted font “%s”", filename)
- return
- end
- local timestamp, db_timestamp
- db_timestamp = status[basefile] and status[basefile].timestamp
- timestamp = lfs.attributes(filename, "modification")
-
- local index_status = newstatus[basefile] or (not texmf and newstatus[basename])
- if index_status and index_status.timestamp == timestamp then
- -- already indexed this run
- return
- end
+--- we return true if the fond is new or re-indexed
+--- string -> dbobj -> dbobj -> bool -> bool
+local load_font = function (fullname, fontnames, newfontnames, texmf)
+ local newmappings = newfontnames.mappings
+ local newstatus = newfontnames.status
+ local mappings = fontnames.mappings
+ local status = fontnames.status
+ local filenames = fontnames.filenames
+ local basename = filebasename(fullname)
+ --- entryname is apparently the identifier a font is
+ --- loaded by; it is different for files in the texmf
+ --- (due to kpse? idk.)
+ --- entryname = texmf : true -> basename | false -> fullname
+ local entryname = texmf and basename or fullname
+
+ if not fullname then return false end
+
+ if names.blacklist[fullname]
+ or names.blacklist[basename]
+ then
+ report("log", 2, "db",
+ "ignoring blacklisted font “%s”", fullname)
+ return false
+ end
+ local timestamp, db_timestamp
+ db_timestamp = status[entryname]
+ and status[entryname].timestamp
+ timestamp = lfs.attributes(fullname, "modification")
+
+ local index_status = newstatus[entryname]
+ or (not texmf and newstatus[basename])
+ local teststat = newstatus[entryname]
+ --- index_status: nil | false | table
+ if index_status and index_status.timestamp == timestamp then
+ -- already indexed this run
+ return false
+ end
- newstatus[basefile] = newstatus[basefile] or { }
- newstatus[basefile].timestamp = timestamp
- newstatus[basefile].index = newstatus[basefile].index or { }
+ newstatus[entryname] = newstatus[entryname] or { }
+ newstatus[entryname].timestamp = timestamp
+ newstatus[entryname].index = newstatus[entryname].index or { }
- if db_timestamp == timestamp and not newstatus[basefile].index[1] then
- for _,v in next, status[basefile].index do
- local index = #newstatus[basefile].index
- newmappings[#newmappings+1] = mappings[v]
- newstatus[basefile].index[index+1] = #newmappings
- end
- report("log", 2, "db", "font “%s” already indexed", basefile)
- return
+ if db_timestamp == timestamp and not newstatus[entryname].index[1] then
+ for _,v in next, status[entryname].index do
+ local index = #newstatus[entryname].index
+ newmappings[#newmappings+1] = mappings[v]
+ newstatus[entryname].index[index+1] = #newmappings
end
- local info = fontloader.info(filename)
- if info then
- if type(info) == "table" and #info > 1 then
- for i in next, info do
- local fullinfo = font_fullinfo(filename, i-1, texmf)
- if not fullinfo then
- return
- end
- local index = newstatus[basefile].index[i]
- if newstatus[basefile].index[i] then
- index = newstatus[basefile].index[i]
- else
- index = #newmappings+1
- end
- newmappings[index] = fullinfo
- newstatus[basefile].index[i] = index
- end
- else
- local fullinfo = font_fullinfo(filename, false, texmf)
+ report("log", 2, "db", "font “%s” already indexed", entryname)
+ return false
+ end
+ local info = fontloaderinfo(fullname)
+
+ if info then
+ if type(info) == "table" and #info > 1 then
+ for i in next, info do
+ local fullinfo = font_fullinfo(fullname, i-1, texmf)
if not fullinfo then
- return
+ return false
end
- local index
- if newstatus[basefile].index[1] then
- index = newstatus[basefile].index[1]
+ local index = newstatus[entryname].index[i]
+ if newstatus[entryname].index[i] then
+ index = newstatus[entryname].index[i]
else
index = #newmappings+1
end
newmappings[index] = fullinfo
- newstatus[basefile].index[1] = index
+ newstatus[entryname].index[i] = index
end
else
- report("log", 1, "db", "failed to load “%s”", basefile)
+ local fullinfo = font_fullinfo(fullname, false, texmf)
+ if not fullinfo then
+ return false
+ end
+ local index
+ if newstatus[entryname].index[1] then
+ index = newstatus[entryname].index[1]
+ else
+ index = #newmappings+1
+ end
+ newmappings[index] = fullinfo
+ newstatus[entryname].index[1] = index
end
+
+ else --- missing info
+ report("log", 1, "db", "failed to load “%s”", entryname)
+ return false
end
+ return true
end
local path_normalize
@@ -800,7 +818,7 @@ for key, value in next, font_extensions do
font_extensions_set[value] = true
end
---- string -> dbobj -> dbobj -> bool -> int
+--- string -> dbobj -> dbobj -> bool -> (int * int)
local scan_dir = function (dirname, fontnames, newfontnames, texmf)
--[[
This function scans a directory and populates the list of fonts
@@ -809,29 +827,31 @@ local scan_dir = function (dirname, fontnames, newfontnames, texmf)
- names is the font database to fill -> no such term!!!
- texmf is a boolean saying if we are scanning a texmf directory
]]
- local n_found = 0 --- total of fonts collected
+ local n_scanned, n_new = 0, 0 --- total of fonts collected
report("log", 2, "db", "scanning", "%s", dirname)
for _,i in next, font_extensions do
for _,ext in next, { i, stringupper(i) } do
local found = dirglob(stringformat("%s/**.%s$", dirname, ext))
- local n_new = #found
+ local n_found = #found
--- note that glob fails silently on broken symlinks, which
--- happens sometimes in TeX Live.
- report("log", 2, "db", "%s '%s' fonts found", n_new, ext)
- n_found = n_found + n_new
- for j=1, n_new do
- local filename = found[j]
- filename = path_normalize(filename)
- report("log", 2, "db", "loading font “%s”", filename)
- load_font(filename, fontnames, newfontnames, texmf)
+ report("log", 2, "db", "%s '%s' fonts found", n_found, ext)
+ n_scanned = n_scanned + n_found
+ for j=1, n_found do
+ local fullname = found[j]
+ fullname = path_normalize(fullname)
+ report("log", 2, "db", "loading font “%s”", fullname)
+ local new = load_font(fullname, fontnames, newfontnames, texmf)
+ if new then n_new = n_new + 1 end
end
end
end
- report("log", 2, "db", "%d fonts found in '%s'", n_found, dirname)
- return n_found
+ report("log", 2, "db", "%d fonts found in '%s'", n_scanned, dirname)
+ return n_scanned, n_new
end
local function scan_texmf_fonts(fontnames, newfontnames)
+ local n_scanned, n_new = 0, 0
--[[
This function scans all fonts in the texmf tree, through kpathsea
variables OPENTYPEFONTS and TTFONTS of texmf.cnf
@@ -845,9 +865,12 @@ local function scan_texmf_fonts(fontnames, newfontnames)
fontdirs = fontdirs .. stringgsub(kpseexpand_path("$TTFONTS"), "^%.", "")
if not stringis_empty(fontdirs) then
for _,d in next, filesplitpath(fontdirs) do
- scan_dir(d, fontnames, newfontnames, true)
+ local found, new = scan_dir(d, fontnames, newfontnames, true)
+ n_scanned = n_scanned + found
+ n_new = n_new + new
end
end
+ return n_scanned, n_new
end
--[[
@@ -981,6 +1004,7 @@ local function get_os_dirs()
end
local function scan_os_fonts(fontnames, newfontnames)
+ local n_scanned, n_new = 0, 0
--[[
This function scans the OS fonts through
- fontcache for Unix (reads the fonts.conf file and scans the directories)
@@ -989,13 +1013,17 @@ local function scan_os_fonts(fontnames, newfontnames)
report("info", 1, "db", "Scanning OS fonts...")
report("info", 2, "db", "Searching in static system directories...")
for _,d in next, get_os_dirs() do
- scan_dir(d, fontnames, newfontnames, false)
+ local found, new = scan_dir(d, fontnames, newfontnames, false)
+ n_scanned = n_scanned + found
+ n_new = n_new + new
end
+ return n_scanned, n_new
end
--- dbobj -> bool -> dbobj
update_names = function (fontnames, force)
local starttime = os.gettimeofday()
+ local n_scanned, n_new = 0, 0
--[[
The main function, scans everything
- “newfontnames” is the final table to return
@@ -1020,19 +1048,25 @@ update_names = function (fontnames, force)
read_blacklist()
--installed_fonts_scanned = false
--scan_installed_fonts(fontnames, newfontnames) --- see fixme above
- scan_texmf_fonts(fontnames, newfontnames)
+ local scanned, new = scan_texmf_fonts(fontnames, newfontnames)
+ n_scanned = n_scanned + scanned
+ n_new = n_new + new
--if not installed_fonts_scanned
--and stringis_empty(kpseexpand_path("$OSFONTDIR"))
if stringis_empty(kpseexpand_path("$OSFONTDIR"))
then
- scan_os_fonts(fontnames, newfontnames)
+ local scanned, new = scan_os_fonts(fontnames, newfontnames)
+ n_scanned = n_scanned + scanned
+ n_new = n_new + new
end
--- stats:
--- before rewrite | after rewrite
--- partial: 804 ms | 701 ms
--- forced: 45384 ms | 44714 ms
- report("info", 1, "db", "Rebuilt in %0.f ms",
- 1000*(os.gettimeofday()-starttime))
+ report("info", 1, "db",
+ "Scanned %d font files; %d new entries.", n_scanned, n_new)
+ report("info", 1, "db",
+ "Rebuilt in %0.f ms", 1000*(os.gettimeofday()-starttime))
return newfontnames
end
@@ -1064,8 +1098,9 @@ scan_external_dir = function (dir)
fonts_loaded = true
end
new_names = tablecopy(old_names)
- scan_dir(dir, old_names, new_names)
+ local n_scanned, n_new = scan_dir(dir, old_names, new_names)
names.data = new_names
+ return n_scanned, n_new
end
--- export functionality to the namespace “fonts.names”