[api-minor] Immediately release the font.data
property once the font been attached to the DOM (PR 11777 follow-up)
*This patch implements https://github.com/mozilla/pdf.js/pull/11777#issuecomment-609741348* This extends the work from PR 11773 and 11777 further, by immediately releasing the `font.data` property once the font been attached to the DOM. By not unnecessarily holding onto this data on the main-thread, we'll thus reduce the memory usage of fonts even further (especially beneficial in longer documents with composite fonts). The new behaviour is controlled by the recently added `fontExtraProperties` API option (adding a new option just for this patch didn't seem necessary), since there's one edge-case in the SVG renderer where the `font.data` property is necessary (see the `pdf2svg` example). Note that while the default viewer does run clean-up with an idle timeout, that timeout will be reset whenever rendering occurs *or* when scrolling happens in the viewer. In practice this means that unless the user doesn't interact with the viewer in *any* way during an extended period of time, currently set to 30 seconds, the `PDFDocumentProxy.cleanup` method will never be called and font resources will thus not be cleaned-up.
This commit is contained in:
parent
c8feea6990
commit
c355f91d2e
@ -86,6 +86,7 @@ function writeSvgToFile(svgElement, filePath) {
|
|||||||
// callback.
|
// callback.
|
||||||
var loadingTask = pdfjsLib.getDocument({
|
var loadingTask = pdfjsLib.getDocument({
|
||||||
data: data,
|
data: data,
|
||||||
|
fontExtraProperties: true,
|
||||||
// Try to export JPEG images directly if they don't need any further
|
// Try to export JPEG images directly if they don't need any further
|
||||||
// processing.
|
// processing.
|
||||||
nativeImageDecoderSupport: pdfjsLib.NativeImageDecoding.DISPLAY,
|
nativeImageDecoderSupport: pdfjsLib.NativeImageDecoding.DISPLAY,
|
||||||
|
@ -2244,20 +2244,22 @@ class WorkerTransport {
|
|||||||
fontRegistry,
|
fontRegistry,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fontLoader.bind(font).then(
|
this.fontLoader
|
||||||
() => {
|
.bind(font)
|
||||||
|
.catch(reason => {
|
||||||
|
return messageHandler.sendWithPromise("FontFallback", { id });
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
if (!params.fontExtraProperties && font.data) {
|
||||||
|
// Immediately release the `font.data` property once the font
|
||||||
|
// has been attached to the DOM, since it's no longer needed,
|
||||||
|
// rather than waiting for a `PDFDocumentProxy.cleanup` call.
|
||||||
|
// Since `font.data` could be very large, e.g. in some cases
|
||||||
|
// multiple megabytes, this will help reduce memory usage.
|
||||||
|
font.data = null;
|
||||||
|
}
|
||||||
this.commonObjs.resolve(id, font);
|
this.commonObjs.resolve(id, font);
|
||||||
},
|
});
|
||||||
reason => {
|
|
||||||
messageHandler
|
|
||||||
.sendWithPromise("FontFallback", {
|
|
||||||
id,
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.commonObjs.resolve(id, font);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case "FontPath":
|
case "FontPath":
|
||||||
case "FontType3Res":
|
case "FontType3Res":
|
||||||
|
@ -1498,7 +1498,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
var isAddToPathSet = !!(
|
var isAddToPathSet = !!(
|
||||||
textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG
|
textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG
|
||||||
);
|
);
|
||||||
const patternFill = current.patternFill && font.data;
|
const patternFill = current.patternFill && !font.missingFile;
|
||||||
|
|
||||||
var addToPath;
|
var addToPath;
|
||||||
if (font.disableFontFace || isAddToPathSet || patternFill) {
|
if (font.disableFontFace || isAddToPathSet || patternFill) {
|
||||||
|
@ -948,6 +948,12 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addFontStyle(fontObj) {
|
addFontStyle(fontObj) {
|
||||||
|
if (!fontObj.data) {
|
||||||
|
throw new Error(
|
||||||
|
"addFontStyle: No font data available, " +
|
||||||
|
'ensure that the "fontExtraProperties" API parameter is set.'
|
||||||
|
);
|
||||||
|
}
|
||||||
if (!this.cssStyle) {
|
if (!this.cssStyle) {
|
||||||
this.cssStyle = this.svgFactory.createElement("svg:style");
|
this.cssStyle = this.svgFactory.createElement("svg:style");
|
||||||
this.cssStyle.setAttributeNS(null, "type", "text/css");
|
this.cssStyle.setAttributeNS(null, "type", "text/css");
|
||||||
@ -972,7 +978,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
this.embedFonts &&
|
this.embedFonts &&
|
||||||
fontObj.data &&
|
!fontObj.missingFile &&
|
||||||
!this.embeddedFonts[fontObj.loadedName]
|
!this.embeddedFonts[fontObj.loadedName]
|
||||||
) {
|
) {
|
||||||
this.addFontStyle(fontObj);
|
this.addFontStyle(fontObj);
|
||||||
|
Loading…
Reference in New Issue
Block a user