in pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/FileSystemFontProvider.java [493:652]
private List<FSFontInfo> loadDiskCache(List<File> files)
{
Set<String> pending = new HashSet<>(files.size());
for (File file : files)
{
pending.add(file.getAbsolutePath());
}
List<FSFontInfo> results = new ArrayList<>();
// Get the disk cache
File diskCacheFile = null;
boolean fileExists = false;
try
{
diskCacheFile = getDiskCacheFile();
fileExists = diskCacheFile.exists();
}
catch (SecurityException e)
{
LOG.debug("Error checking for file existence", e);
}
if (fileExists)
{
try (BufferedReader reader = new BufferedReader(new FileReader(diskCacheFile)))
{
// consequent lines usually share the same font file (e.g. "Courier", "Courier-Bold", "Courier-Oblique").
// unused if SKIP_CHECKSUMS
File lastFile = null;
String lastHash = null;
//
String line;
while ((line = reader.readLine()) != null)
{
String[] parts = line.split("\\|", 12);
if (parts.length < 10)
{
LOG.warn("Incorrect line '{}' in font disk cache is skipped", line);
continue;
}
String postScriptName;
FontFormat format;
CIDSystemInfo cidSystemInfo = null;
int usWeightClass = -1;
int sFamilyClass = -1;
int ulCodePageRange1;
int ulCodePageRange2;
int macStyle = -1;
byte[] panose = null;
File fontFile;
String hash = "";
long lastModified = 0;
postScriptName = parts[0];
format = FontFormat.valueOf(parts[1]);
if (!parts[2].isEmpty())
{
String[] ros = parts[2].split("-");
cidSystemInfo = new CIDSystemInfo(ros[0], ros[1], Integer.parseInt(ros[2]));
}
if (!parts[3].isEmpty())
{
usWeightClass = (int)Long.parseLong(parts[3], 16);
}
if (!parts[4].isEmpty())
{
sFamilyClass = (int)Long.parseLong(parts[4], 16);
}
ulCodePageRange1 = (int)Long.parseLong(parts[5], 16);
ulCodePageRange2 = (int)Long.parseLong(parts[6], 16);
if (!parts[7].isEmpty())
{
macStyle = (int)Long.parseLong(parts[7], 16);
}
if (!parts[8].isEmpty())
{
panose = new byte[10];
for (int i = 0; i < 10; i ++)
{
String str = parts[8].substring(i * 2, i * 2 + 2);
int b = Integer.parseInt(str, 16);
panose[i] = (byte)(b & 0xff);
}
}
fontFile = new File(parts[9]);
if (parts.length >= 12 && !parts[10].isEmpty() && !parts[11].isEmpty())
{
hash = parts[10];
lastModified = Long.parseLong(parts[11]);
}
if (fontFile.exists())
{
// if the file exists, find out whether it's the same file.
// first check whether time is different and if yes, whether hash is different
boolean keep = fontFile.lastModified() == lastModified;
if (!keep && !SKIP_CHECKSUMS)
{
String newHash;
if (hash.equals(lastHash) && fontFile.equals(lastFile))
{
newHash = lastHash; // already computed
}
else
{
try
{
newHash = computeHash(Files.newInputStream(fontFile.toPath()));
lastFile = fontFile;
lastHash = newHash;
}
catch (IOException ex)
{
LOG.debug(() -> "Error reading font file " + fontFile.getAbsolutePath(), ex);
newHash = "<err>";
}
}
if (hash.equals(newHash))
{
keep = true;
lastModified = fontFile.lastModified();
}
}
if (keep)
{
FSFontInfo info = new FSFontInfo(fontFile, format, postScriptName,
cidSystemInfo, usWeightClass, sFamilyClass, ulCodePageRange1,
ulCodePageRange2, macStyle, panose, this, hash, lastModified);
results.add(info);
}
else
{
LOG.debug("Font file {} is different", fontFile.getAbsolutePath());
continue; // don't remove from "pending"
}
}
else
{
LOG.debug("Font file {} not found, skipped", fontFile.getAbsolutePath());
}
pending.remove(fontFile.getAbsolutePath());
}
}
catch (IOException e)
{
LOG.warn("Error loading font cache, will be re-built", e);
return null;
}
}
if (!pending.isEmpty())
{
// re-build the entire cache if we encounter un-cached fonts (could be optimised)
LOG.info("{} new font files found, font cache will be re-built", pending.size());
return null;
}
return results;
}