/* * Copyright (C) 2022 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ import {exec} from 'child_process'; import config from '../icons.config.mjs'; import {statSync} from 'fs'; import {getUsedIconsHtml, getUsedIconsTS} from './gather-used-icons.mjs'; import {getCodePoints} from './get-code-points.mjs'; /** * @param {string[] | string} command * @returns {Promise} */ async function run(command) { const fullCommand = Array.isArray(command) ? command.join(' ') : command; console.log(`>> ${fullCommand}`); return new Promise((resolve, reject) => { exec(fullCommand, (error, stdout, stderr) => { if (error) { reject(error); } else if (stderr) { reject(stderr); } else { resolve(stdout.trim()); } }); }); } /** * */ async function minifyIconFont() { /** @type {Set} */ const icons = new Set(); for (const iconSet of [ ...Object.values(config.additionalIcons || []), ...Object.values(await getUsedIconsTS(config.scriptGlob)), ...Object.values(await getUsedIconsHtml(config.htmlGlob)), ]) { for (const icon of iconSet) { icons.add(icon); } } const glyphs = ['5f-7a', '30-39', ...(await getCodePoints([...icons]))].sort(); console.log( await run([ 'pyftsubset', `"${config.inputPath}"`, `--unicodes=${glyphs.join(',')}`, '--no-layout-closure', `--output-file="${config.outputPath}"`, '--flavor=woff2', ]), ); console.log(`${glyphs.length} Used Icons Total`); console.log(`Minified font saved to ${config.outputPath}`); const result = statSync(config.outputPath).size; const before = statSync(config.inputPath).size; console.log( `${toByteUnit(before)} > ${toByteUnit(result)} (${(((before - result) / before) * 100).toFixed( 2, )}% Reduction)`, ); } // eslint-disable-next-line unicorn/prefer-top-level-await minifyIconFont(); /** * Bytes to respective units * @param {number} value * @returns {string} */ function toByteUnit(value) { if (value < 1024) { return `${value}B`; } else if (value < 1024 * 1024) { return `${(value / 1024).toFixed(2)}KB`; } else { return `${(value / 1024 / 1024).toFixed(2)}MB`; } }