Add a cache to avoid to load several times a local font
On my computer, it takes few tenths of a second to load a local font. Since a font can be used several times in a document, the cache will improve performances.
This commit is contained in:
parent
2d2f7b315e
commit
cfb908c999
@ -81,6 +81,7 @@ class Catalog {
|
||||
this.pageKidsCountCache = new RefSetCache();
|
||||
this.pageIndexCache = new RefSetCache();
|
||||
this.nonBlendModesSet = new RefSet();
|
||||
this.systemFontCache = new Map();
|
||||
}
|
||||
|
||||
get version() {
|
||||
@ -1062,6 +1063,7 @@ class Catalog {
|
||||
this.fontCache.clear();
|
||||
this.builtInCMapCache.clear();
|
||||
this.standardFontDataCache.clear();
|
||||
this.systemFontCache.clear();
|
||||
}
|
||||
|
||||
async getPageDict(pageIndex) {
|
||||
|
@ -74,6 +74,7 @@ class Page {
|
||||
builtInCMapCache,
|
||||
standardFontDataCache,
|
||||
globalImageCache,
|
||||
systemFontCache,
|
||||
nonBlendModesSet,
|
||||
xfaFactory,
|
||||
}) {
|
||||
@ -86,6 +87,7 @@ class Page {
|
||||
this.builtInCMapCache = builtInCMapCache;
|
||||
this.standardFontDataCache = standardFontDataCache;
|
||||
this.globalImageCache = globalImageCache;
|
||||
this.systemFontCache = systemFontCache;
|
||||
this.nonBlendModesSet = nonBlendModesSet;
|
||||
this.evaluatorOptions = pdfManager.evaluatorOptions;
|
||||
this.resourcesPromise = null;
|
||||
@ -270,6 +272,7 @@ class Page {
|
||||
builtInCMapCache: this.builtInCMapCache,
|
||||
standardFontDataCache: this.standardFontDataCache,
|
||||
globalImageCache: this.globalImageCache,
|
||||
systemFontCache: this.systemFontCache,
|
||||
options: this.evaluatorOptions,
|
||||
});
|
||||
|
||||
@ -321,6 +324,7 @@ class Page {
|
||||
builtInCMapCache: this.builtInCMapCache,
|
||||
standardFontDataCache: this.standardFontDataCache,
|
||||
globalImageCache: this.globalImageCache,
|
||||
systemFontCache: this.systemFontCache,
|
||||
options: this.evaluatorOptions,
|
||||
});
|
||||
|
||||
@ -390,6 +394,7 @@ class Page {
|
||||
builtInCMapCache: this.builtInCMapCache,
|
||||
standardFontDataCache: this.standardFontDataCache,
|
||||
globalImageCache: this.globalImageCache,
|
||||
systemFontCache: this.systemFontCache,
|
||||
options: this.evaluatorOptions,
|
||||
});
|
||||
|
||||
@ -533,6 +538,7 @@ class Page {
|
||||
builtInCMapCache: this.builtInCMapCache,
|
||||
standardFontDataCache: this.standardFontDataCache,
|
||||
globalImageCache: this.globalImageCache,
|
||||
systemFontCache: this.systemFontCache,
|
||||
options: this.evaluatorOptions,
|
||||
});
|
||||
|
||||
@ -602,6 +608,7 @@ class Page {
|
||||
builtInCMapCache: this.builtInCMapCache,
|
||||
standardFontDataCache: this.standardFontDataCache,
|
||||
globalImageCache: this.globalImageCache,
|
||||
systemFontCache: this.systemFontCache,
|
||||
options: this.evaluatorOptions,
|
||||
});
|
||||
|
||||
@ -1476,6 +1483,7 @@ class PDFDocument {
|
||||
builtInCMapCache: catalog.builtInCMapCache,
|
||||
standardFontDataCache: catalog.standardFontDataCache,
|
||||
globalImageCache: catalog.globalImageCache,
|
||||
systemFontCache: catalog.systemFontCache,
|
||||
nonBlendModesSet: catalog.nonBlendModesSet,
|
||||
xfaFactory,
|
||||
});
|
||||
@ -1574,6 +1582,7 @@ class PDFDocument {
|
||||
builtInCMapCache: catalog.builtInCMapCache,
|
||||
standardFontDataCache: catalog.standardFontDataCache,
|
||||
globalImageCache: catalog.globalImageCache,
|
||||
systemFontCache: catalog.systemFontCache,
|
||||
nonBlendModesSet: catalog.nonBlendModesSet,
|
||||
xfaFactory: null,
|
||||
})
|
||||
|
@ -215,6 +215,7 @@ class PartialEvaluator {
|
||||
builtInCMapCache,
|
||||
standardFontDataCache,
|
||||
globalImageCache,
|
||||
systemFontCache,
|
||||
options = null,
|
||||
}) {
|
||||
this.xref = xref;
|
||||
@ -225,6 +226,7 @@ class PartialEvaluator {
|
||||
this.builtInCMapCache = builtInCMapCache;
|
||||
this.standardFontDataCache = standardFontDataCache;
|
||||
this.globalImageCache = globalImageCache;
|
||||
this.systemFontCache = systemFontCache;
|
||||
this.options = options || DefaultPartialEvaluatorOptions;
|
||||
this.parsingType3Font = false;
|
||||
|
||||
@ -4197,6 +4199,7 @@ class PartialEvaluator {
|
||||
properties.isInternalFont = !!file;
|
||||
if (!properties.isInternalFont && this.options.useSystemFonts) {
|
||||
properties.systemFontInfo = getFontSubstitution(
|
||||
this.systemFontCache,
|
||||
this.idFactory,
|
||||
this.options.standardFontDataUrl,
|
||||
baseFontName,
|
||||
@ -4309,6 +4312,7 @@ class PartialEvaluator {
|
||||
isInternalFont = !!fontFile;
|
||||
if (!isInternalFont && this.options.useSystemFonts) {
|
||||
systemFontInfo = getFontSubstitution(
|
||||
this.systemFontCache,
|
||||
this.idFactory,
|
||||
this.options.standardFontDataUrl,
|
||||
fontName.name,
|
||||
|
@ -374,6 +374,7 @@ function makeLocal(prepend, local) {
|
||||
* }
|
||||
* or use the FontFace API.
|
||||
*
|
||||
* @param {Map} systemFontCache The cache of local fonts.
|
||||
* @param {Object} idFactory The ids factory.
|
||||
* @param {String} localFontPath Path to the fonts directory.
|
||||
* @param {String} baseFontName The font name to be substituted.
|
||||
@ -382,6 +383,7 @@ function makeLocal(prepend, local) {
|
||||
* @returns an Object with the CSS, the loaded name, the src and the style.
|
||||
*/
|
||||
function getFontSubstitution(
|
||||
systemFontCache,
|
||||
idFactory,
|
||||
localFontPath,
|
||||
baseFontName,
|
||||
@ -393,6 +395,12 @@ function getFontSubstitution(
|
||||
// just replace them by a dash.
|
||||
baseFontName = normalizeFontName(baseFontName);
|
||||
|
||||
const key = baseFontName;
|
||||
let substitutionInfo = systemFontCache.get(key);
|
||||
if (substitutionInfo) {
|
||||
return substitutionInfo;
|
||||
}
|
||||
|
||||
// First, check if we've a substitution for the base font.
|
||||
let substitution = substitutionMap.get(baseFontName);
|
||||
if (!substitution) {
|
||||
@ -416,6 +424,7 @@ function getFontSubstitution(
|
||||
const loadedName = `${idFactory.getDocId()}_sf_${idFactory.createFontId()}`;
|
||||
if (!substitution) {
|
||||
if (!validateFontName(baseFontName)) {
|
||||
systemFontCache.set(key, null);
|
||||
// If the baseFontName is not valid we don't want to use it.
|
||||
return null;
|
||||
}
|
||||
@ -427,12 +436,14 @@ function getFontSubstitution(
|
||||
(bold && BOLD) ||
|
||||
(italic && ITALIC) ||
|
||||
NORMAL;
|
||||
return {
|
||||
substitutionInfo = {
|
||||
css: `${loadedName},sans-serif`,
|
||||
loadedName,
|
||||
src: `local(${baseFontName})`,
|
||||
style,
|
||||
};
|
||||
systemFontCache.set(key, substitutionInfo);
|
||||
return substitutionInfo;
|
||||
}
|
||||
|
||||
while (substitution.alias) {
|
||||
@ -467,12 +478,14 @@ function getFontSubstitution(
|
||||
src = `local(${baseFontName}),${src}`;
|
||||
}
|
||||
|
||||
return {
|
||||
substitutionInfo = {
|
||||
css: `${loadedName},${ultimate}`,
|
||||
loadedName,
|
||||
src,
|
||||
style,
|
||||
};
|
||||
systemFontCache.set(key, substitutionInfo);
|
||||
return substitutionInfo;
|
||||
}
|
||||
|
||||
export { getFontSubstitution };
|
||||
|
@ -25,6 +25,8 @@ import {
|
||||
import { isNodeJS } from "../shared/is_node.js";
|
||||
|
||||
class FontLoader {
|
||||
#systemFonts = new Set();
|
||||
|
||||
constructor({
|
||||
ownerDocument = globalThis.document,
|
||||
styleElement = null, // For testing only.
|
||||
@ -69,6 +71,7 @@ class FontLoader {
|
||||
this._document.fonts.delete(nativeFontFace);
|
||||
}
|
||||
this.nativeFontFaces.clear();
|
||||
this.#systemFonts.clear();
|
||||
|
||||
if (this.styleElement) {
|
||||
// Note: ChildNode.remove doesn't throw if the parentNode is undefined.
|
||||
@ -78,6 +81,9 @@ class FontLoader {
|
||||
}
|
||||
|
||||
async loadSystemFont(info) {
|
||||
if (!info || this.#systemFonts.has(info.loadedName)) {
|
||||
return;
|
||||
}
|
||||
assert(
|
||||
!this.disableFontFace,
|
||||
"loadSystemFont shouldn't be called when `disableFontFace` is set."
|
||||
@ -89,6 +95,7 @@ class FontLoader {
|
||||
this.addNativeFontFace(fontFace);
|
||||
try {
|
||||
await fontFace.load();
|
||||
this.#systemFonts.add(loadedName);
|
||||
} catch {
|
||||
warn(
|
||||
`Cannot load system font: ${loadedName} for style ${style.style} and weight ${style.weight}.`
|
||||
|
@ -130,6 +130,7 @@ describe("annotation", function () {
|
||||
fontCache: new RefSetCache(),
|
||||
builtInCMapCache,
|
||||
standardFontDataCache: new Map(),
|
||||
systemFontCache: new Map(),
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user