From e69ecb9ff819b6365829bd7778662fd348bfeca9 Mon Sep 17 00:00:00 2001 From: Balearica Date: Wed, 4 Dec 2024 07:55:58 -0800 Subject: [PATCH] Added function for adding arbitrary fonts --- js/containers/fontContainer.js | 55 +++++++++++++++++++++++++++++++++ js/containers/imageContainer.js | 47 +--------------------------- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/js/containers/fontContainer.js b/js/containers/fontContainer.js index 2dc19d3..dc9afcb 100644 --- a/js/containers/fontContainer.js +++ b/js/containers/fontContainer.js @@ -273,6 +273,61 @@ export class FontCont { /** @type {?('latin'|'all')} */ static glyphSet = null; + /** + * Load fonts from an ArrayBuffer containing arbitrary font data. + * Supports .ttf, .otf, and .woff formats. + * This function should only be used for fonts we do not provide, such as user-uploaded fonts. + * @param {ArrayBuffer} src + */ + static addFontFromFile = async (src) => { + let fontObj; + let fontData; + try { + fontObj = await loadOpentype(src); + // It is common for raw fonts embedded in PDFs to be invalid and rejected by the OTS, but running them through opentype.js fixes them. + // This appears to be because of the way that fonts are subsetted in PDFs. + fontData = fontObj.toArrayBuffer(); + } catch (error) { + console.error('Error loading font.'); + console.error(error); + return; + } + + const fontNameEmbedded = fontObj.names.postScriptName.en; + + let fontStyle = 'normal'; + if (fontNameEmbedded.match(/italic/i)) { + fontStyle = 'italic'; + } else if (fontNameEmbedded.match(/bold/i)) { + fontStyle = 'bold'; + } + + // mupdf makes changes to font names, so we need to do the same. + // Font names in the form `MEDJCO+CenturySchoolbook` are changed to `CenturySchoolbook`. + // Spaces are replaced with underscores. + const fontName = fontNameEmbedded.replace(/[^+]+\+/g, '').replace(/\s/g, '_'); + + if (!FontCont.doc?.[fontName]?.[fontStyle]) { + try { + const fontContainer = new FontContainerFont(fontName, fontStyle, fontData, false, fontObj); + + if (!FontCont.doc) { + FontCont.doc = {}; + } + + if (!FontCont.doc[fontName]) { + FontCont.doc[fontName] = {}; + } + + FontCont.doc[fontName][fontStyle] = fontContainer; + } catch (error) { + console.error(`Error loading font ${fontName} ${fontStyle}.`); + } + } else { + console.warn(`Font ${fontName} ${fontStyle} already exists.`); + } + }; + /** * Decide whether to use the optimized version of a font family. * Note that even when this function returns `true`, optimized versions of every style will not exist. diff --git a/js/containers/imageContainer.js b/js/containers/imageContainer.js index dc23ce8..a3da99d 100644 --- a/js/containers/imageContainer.js +++ b/js/containers/imageContainer.js @@ -430,52 +430,7 @@ export class ImageCache { muPDFScheduler.extractAllFonts().then(async (x) => { for (let i = 0; i < x.length; i++) { const src = x[i].buffer; - let fontObj; - let fontData; - try { - fontObj = await loadOpentype(src); - // It is common for raw fonts embedded in PDFs to be invalid and rejected by the OTS, but running them through opentype.js fixes them. - // This appears to be because of the way that fonts are subsetted in PDFs. - fontData = fontObj.toArrayBuffer(); - } catch (error) { - console.error(`Error loading font ${i}.`); - console.error(error); - continue; - } - - const fontNameEmbedded = fontObj.names.postScriptName.en; - - let fontStyle = 'normal'; - if (fontNameEmbedded.match(/italic/i)) { - fontStyle = 'italic'; - } else if (fontNameEmbedded.match(/bold/i)) { - fontStyle = 'bold'; - } - - // mupdf makes changes to font names, so we need to do the same. - // Font names in the form `MEDJCO+CenturySchoolbook` are changed to `CenturySchoolbook`. - // Spaces are replaced with underscores. - const fontName = fontNameEmbedded.replace(/[^+]+\+/g, '').replace(/\s/g, '_'); - - if (!FontCont.doc?.[fontName]?.[fontStyle]) { - try { - const fontContainer = new FontContainerFont(fontName, fontStyle, fontData, false, fontObj); - - if (!FontCont.doc) { - FontCont.doc = {}; - } - - if (!FontCont.doc[fontName]) { - FontCont.doc[fontName] = {}; - } - - FontCont.doc[fontName][fontStyle] = fontContainer; - } catch (error) { - console.error(`Error loading font ${fontName} ${fontStyle}.`); - } - } else { - console.warn(`Font ${fontName} ${fontStyle} already exists.`); - } + FontCont.addFontFromFile(src); } await updateFontContWorkerMain(); });