subfont 6.12.4 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -7
- package/README.md +1 -2
- package/lib/HeadlessBrowser.js +5 -2
- package/lib/getFontInfo.js +27 -0
- package/lib/parseCommandLineOptions.js +6 -0
- package/lib/subfont.js +5 -0
- package/lib/subsetFonts.js +117 -24
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
### v7.1.0 (2023-04-15)
|
|
2
|
+
|
|
3
|
+
- [#170](https://github.com/Munter/subfont/pull/170) Use harfbuzzjs instead of fontkit ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
4
|
+
|
|
5
|
+
### v7.0.0 (2023-04-08)
|
|
6
|
+
|
|
7
|
+
#### Pull requests
|
|
8
|
+
|
|
9
|
+
- [#169](https://github.com/Munter/subfont/pull/169) Support full instancing of variable fonts ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
10
|
+
|
|
11
|
+
#### Commits to master
|
|
12
|
+
|
|
13
|
+
- [Also tell prettier to ignore the puppeteer-browsers dir](https://github.com/Munter/subfont/commit/0e55e8838902d4c4730176313359abbda1c8ebd6) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
14
|
+
- [Revert "Drop node.js 14"](https://github.com/Munter/subfont/commit/5e54905f05bc398b4aebdbefeb766c42664866b3) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
15
|
+
- [Tell eslint to ignore the puppeteer-browsers dir](https://github.com/Munter/subfont/commit/99bca776a0bd7fab4c3e9c1084c23ae5f7c4e18b) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
16
|
+
- [Drop node.js 14](https://github.com/Munter/subfont/commit/0dcf1ed53fa20f7eb4585e6e3813fa8d97aefae5) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
17
|
+
- [Tolerate different moch console call orders](https://github.com/Munter/subfont/commit/046971fa1b9fb4096b108cd777f18c34bb938438) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
18
|
+
- [+10 more](https://github.com/Munter/subfont/compare/v6.12.4...v7.0.0)
|
|
19
|
+
|
|
20
|
+
### v6.12.4 (2023-01-06)
|
|
21
|
+
|
|
22
|
+
- [Adapt to a backwards incompatible change in @hookun\/parse-animation-shorthand 0.1.5](https://github.com/Munter/subfont/commit/0d024aeaca1ac4ebb52ecacf9e20151d3102b1df) ([Andreas Lind](mailto:andreas.lind@workday.com))
|
|
23
|
+
|
|
1
24
|
### v6.12.3 (2023-01-06)
|
|
2
25
|
|
|
3
26
|
- [Update @hookun\/parse-animation-shorthand to ^0.1.5, fixes \#168](https://github.com/Munter/subfont/commit/ec19b28392e02c2a4cc42e0124cca5fce4c2ba32) ([Andreas Lind](mailto:andreas.lind@workday.com))
|
|
@@ -54,9 +77,13 @@
|
|
|
54
77
|
- [Update subset-font to ^1.5.0](https://github.com/Munter/subfont/commit/ba79ef6db81cedfd0e52672b530ca3afddd68a94) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
55
78
|
- [Fix warning about missing glyphs for BMP chars](https://github.com/Munter/subfont/commit/5ba0168f35bfef33f9bb9cc8a6d64de8fa1d5585) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
56
79
|
- [Fix CHANGELOG generation in preversion script](https://github.com/Munter/subfont/commit/3ea696f8c336c6072411c9817c0c2f5b8d8d61b9) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
80
|
+
|
|
81
|
+
### v6.6.1 (2022-07-09)
|
|
82
|
+
|
|
83
|
+
- [ugrvw](https://github.com/Munter/subfont/commit/5ccb873025f9790faf65641551df1a7e65fbfdbf) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
57
84
|
- [Fix CHANGELOG https:\/\/github.com\/Munter\/subfont\/commit\/5365689a5a925304a158fddef2b6af702857371c\#r78084394](https://github.com/Munter/subfont/commit/d42c7a2cffd33662d42d4532c45cb8b90080f128) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
58
85
|
- [Expect browserslist to only prescribe woff I guess the browser features + usage statistics finally changed so woff isn't needed](https://github.com/Munter/subfont/commit/b70db9b769955cabbda2f2a76f2e7758f9968ec7) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
59
|
-
- [+
|
|
86
|
+
- [Tests: Tolerate u+ in unicode-range \(I guess an in-range dep changed\)](https://github.com/Munter/subfont/commit/92a7871457246b64a997c0bffd9bb2766655d811) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
60
87
|
|
|
61
88
|
### v6.6.0 (2022-07-09)
|
|
62
89
|
|
|
@@ -343,16 +370,13 @@
|
|
|
343
370
|
#### Pull requests
|
|
344
371
|
|
|
345
372
|
- [#76](https://github.com/Munter/subfont/pull/76) Fix the prettier setup ([Andreas Lind](mailto:andreas.lind@peakon.com))
|
|
373
|
+
- [#75](https://github.com/Munter/subfont/pull/75) Fix omitFallbacks with Google Web Fonts ([Andreas Lind](mailto:andreas.lind@peakon.com))
|
|
346
374
|
|
|
347
375
|
#### Commits to master
|
|
348
376
|
|
|
349
377
|
- [Switch to the official css-font-parser now that bramstein\/css-font-parser\#7 has been merged and released](https://github.com/Munter/subfont/commit/457c7f0e4cef0a8c1bd8f816c23ace64c9987424) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
350
378
|
- [Don't populate source map relations](https://github.com/Munter/subfont/commit/5c07218b6f1dcc6fad88702a3bcb7b33bf9df54e) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
351
379
|
|
|
352
|
-
### v4.1.2 (2020-01-09)
|
|
353
|
-
|
|
354
|
-
- [#75](https://github.com/Munter/subfont/pull/75) Fix omitFallbacks with Google Web Fonts ([Andreas Lind](mailto:andreas.lind@peakon.com))
|
|
355
|
-
|
|
356
380
|
### v4.1.1 (2020-01-04)
|
|
357
381
|
|
|
358
382
|
- [Add regression test](https://github.com/Munter/subfont/commit/46eddce9c09268dbde459b1f98fe5cec9e4c98f5) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
@@ -383,8 +407,7 @@
|
|
|
383
407
|
- [Add vscode debugger launch configuration for the test suite](https://github.com/Munter/subfont/commit/f8f9abc42909c556765555cc49f44eb40a9194db) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
384
408
|
- [Guard against an already detached relation when cleaning up](https://github.com/Munter/subfont/commit/6392fc359222772c9033a58a9020e3b35487d019) ([Andreas Lind](mailto:andreaslindpetersen@gmail.com))
|
|
385
409
|
|
|
386
|
-
### v4.0.3
|
|
387
|
-
|
|
410
|
+
### v4.0.3
|
|
388
411
|
#### Pull requests
|
|
389
412
|
|
|
390
413
|
- [#67](https://github.com/Munter/subfont/pull/67) Only warn about missing fonttools install if we are actually trying t… ([Peter Müller](mailto:munter@fumle.dk))
|
package/README.md
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
[](http://badge.fury.io/js/subfont)
|
|
4
4
|
[](https://travis-ci.org/Munter/subfont)
|
|
5
5
|
[](https://coveralls.io/r/Munter/subfont?branch=master)
|
|
6
|
-
[](https://david-dm.org/Munter/subfont) [](https://greenkeeper.io/)
|
|
7
6
|
|
|
8
7
|
A command line tool to statically analyse your page in order to generate the most optimal web font subsets, then inject them into your page.
|
|
9
8
|
|
|
@@ -25,7 +24,7 @@ Subfont will:
|
|
|
25
24
|
Currently supported font services:
|
|
26
25
|
|
|
27
26
|
- Google fonts
|
|
28
|
-
- Local fonts
|
|
27
|
+
- Local fonts
|
|
29
28
|
|
|
30
29
|
**If you know of font services with liberal font usage licenses, open an issue and we'll add support for them**
|
|
31
30
|
|
package/lib/HeadlessBrowser.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const urlTools = require('urltools');
|
|
2
2
|
const puppeteer = require('puppeteer-core');
|
|
3
|
+
const pathModule = require('path');
|
|
3
4
|
|
|
4
5
|
async function transferResults(jsHandle) {
|
|
5
6
|
const results = await jsHandle.jsonValue();
|
|
@@ -12,8 +13,10 @@ async function transferResults(jsHandle) {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
async function downloadOrLocatePreferredBrowserRevision() {
|
|
15
|
-
const browserFetcher = puppeteer.
|
|
16
|
-
|
|
16
|
+
const browserFetcher = new puppeteer.BrowserFetcher({
|
|
17
|
+
path: pathModule.resolve(__dirname, '..', 'puppeteer-browsers'),
|
|
18
|
+
});
|
|
19
|
+
const preferredRevision = puppeteer.default.defaultBrowserRevision;
|
|
17
20
|
const localRevisions = await browserFetcher.localRevisions();
|
|
18
21
|
let revisionInfo;
|
|
19
22
|
if (localRevisions.includes(preferredRevision)) {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const fontverter = require('fontverter');
|
|
2
|
+
|
|
3
|
+
async function getFontInfoFromBuffer(buffer) {
|
|
4
|
+
const harfbuzzJs = await require('harfbuzzjs');
|
|
5
|
+
|
|
6
|
+
const blob = harfbuzzJs.createBlob(await fontverter.convert(buffer, 'sfnt')); // Load the font data into something Harfbuzz can use
|
|
7
|
+
const face = harfbuzzJs.createFace(blob, 0); // Select the first font in the file (there's normally only one!)
|
|
8
|
+
|
|
9
|
+
const fontInfo = {
|
|
10
|
+
characterSet: Array.from(face.collectUnicodes()),
|
|
11
|
+
variationAxes: face.getAxisInfos(),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
face.destroy();
|
|
15
|
+
blob.destroy();
|
|
16
|
+
|
|
17
|
+
return fontInfo;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const fontInfoPromiseByBuffer = new WeakMap();
|
|
21
|
+
|
|
22
|
+
module.exports = function getFontInfo(buffer) {
|
|
23
|
+
if (!fontInfoPromiseByBuffer.has(buffer)) {
|
|
24
|
+
fontInfoPromiseByBuffer.set(buffer, getFontInfoFromBuffer(buffer));
|
|
25
|
+
}
|
|
26
|
+
return fontInfoPromiseByBuffer.get(buffer);
|
|
27
|
+
};
|
|
@@ -92,6 +92,12 @@ module.exports = function parseCommandLineOptions(argv) {
|
|
|
92
92
|
type: 'boolean',
|
|
93
93
|
default: false,
|
|
94
94
|
})
|
|
95
|
+
.options('instance', {
|
|
96
|
+
describe:
|
|
97
|
+
'Experimentally instance variable fonts when every variation axis only has one value (only supports full instancing for now)',
|
|
98
|
+
type: 'boolean',
|
|
99
|
+
default: false,
|
|
100
|
+
})
|
|
95
101
|
.options('silent', {
|
|
96
102
|
alias: 's',
|
|
97
103
|
describe: `Do not write anything to stdout`,
|
package/lib/subfont.js
CHANGED
|
@@ -23,6 +23,7 @@ module.exports = async function subfont(
|
|
|
23
23
|
relativeUrls = false,
|
|
24
24
|
fallbacks = true,
|
|
25
25
|
dynamic = false,
|
|
26
|
+
instance = false,
|
|
26
27
|
browsers,
|
|
27
28
|
text,
|
|
28
29
|
},
|
|
@@ -227,6 +228,7 @@ module.exports = async function subfont(
|
|
|
227
228
|
hrefType: relativeUrls ? 'relative' : 'rootRelative',
|
|
228
229
|
text,
|
|
229
230
|
dynamic,
|
|
231
|
+
instance,
|
|
230
232
|
console,
|
|
231
233
|
});
|
|
232
234
|
|
|
@@ -357,6 +359,9 @@ module.exports = async function subfont(
|
|
|
357
359
|
fontUsage.smallestOriginalSize !== undefined &&
|
|
358
360
|
fontUsage.smallestSubsetSize !== undefined
|
|
359
361
|
) {
|
|
362
|
+
if (fontUsage.variationAxes) {
|
|
363
|
+
status += ', fully instanced';
|
|
364
|
+
}
|
|
360
365
|
status += `, ${prettyBytes(fontUsage.smallestOriginalSize)} (${
|
|
361
366
|
fontUsage.smallestOriginalFormat
|
|
362
367
|
}) => ${prettyBytes(fontUsage.smallestSubsetSize)} (${
|
package/lib/subsetFonts.js
CHANGED
|
@@ -20,13 +20,13 @@ const injectSubsetDefinitions = require('./injectSubsetDefinitions');
|
|
|
20
20
|
const cssFontParser = require('css-font-parser');
|
|
21
21
|
const cssListHelpers = require('css-list-helpers');
|
|
22
22
|
const LinesAndColumns = require('lines-and-columns').default;
|
|
23
|
-
const fontkit = require('fontkit');
|
|
24
23
|
const crypto = require('crypto');
|
|
25
24
|
|
|
26
25
|
const unquote = require('./unquote');
|
|
27
26
|
const normalizeFontPropertyValue = require('./normalizeFontPropertyValue');
|
|
28
27
|
const getCssRulesByProperty = require('./getCssRulesByProperty');
|
|
29
28
|
const unicodeRange = require('./unicodeRange');
|
|
29
|
+
const getFontInfo = require('./getFontInfo');
|
|
30
30
|
|
|
31
31
|
const googleFontsCssUrlRegex = /^(?:https?:)?\/\/fonts\.googleapis\.com\/css/;
|
|
32
32
|
|
|
@@ -374,14 +374,59 @@ function asyncLoadStyleRelationWithFallback(
|
|
|
374
374
|
htmlOrSvgAsset.markDirty();
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
-
function getSubsetPromiseId(fontUsage, format) {
|
|
378
|
-
return [
|
|
377
|
+
function getSubsetPromiseId(fontUsage, format, variationAxes = null) {
|
|
378
|
+
return [
|
|
379
|
+
fontUsage.text,
|
|
380
|
+
fontUsage.fontUrl,
|
|
381
|
+
format,
|
|
382
|
+
JSON.stringify(variationAxes),
|
|
383
|
+
].join('\x1d');
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
async function getFullyPinnedVariationAxes(
|
|
387
|
+
assetGraph,
|
|
388
|
+
fontUrl,
|
|
389
|
+
seenAxisValuesByFontUrlAndAxisName
|
|
390
|
+
) {
|
|
391
|
+
const fontInfo = await getFontInfo(
|
|
392
|
+
assetGraph.findAssets({ url: fontUrl })[0].rawSrc
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
let variationAxes;
|
|
396
|
+
const fontVariationEntries = Object.entries(fontInfo.variationAxes);
|
|
397
|
+
const seenAxisValuesByAxisName =
|
|
398
|
+
seenAxisValuesByFontUrlAndAxisName.get(fontUrl);
|
|
399
|
+
if (fontVariationEntries.length > 0 && seenAxisValuesByAxisName) {
|
|
400
|
+
variationAxes = {};
|
|
401
|
+
let everyAxisPinned = true;
|
|
402
|
+
for (const [
|
|
403
|
+
axisName,
|
|
404
|
+
{ min, max, default: defaultValue },
|
|
405
|
+
] of fontVariationEntries) {
|
|
406
|
+
let seenAxisValues = seenAxisValuesByAxisName.get(axisName);
|
|
407
|
+
if (!seenAxisValues && !ignoredVariationAxes.has(axisName)) {
|
|
408
|
+
seenAxisValues = new Set([defaultValue]);
|
|
409
|
+
}
|
|
410
|
+
if (seenAxisValues && seenAxisValues.size === 1) {
|
|
411
|
+
variationAxes[axisName] = _.clamp([...seenAxisValues][0], min, max);
|
|
412
|
+
} else {
|
|
413
|
+
everyAxisPinned = false;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (!everyAxisPinned) {
|
|
417
|
+
// Not all variation axes can be fully pinned, bail out
|
|
418
|
+
variationAxes = undefined;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return variationAxes;
|
|
379
422
|
}
|
|
380
423
|
|
|
381
424
|
async function getSubsetsForFontUsage(
|
|
382
425
|
assetGraph,
|
|
383
426
|
htmlOrSvgAssetTextsWithProps,
|
|
384
|
-
formats
|
|
427
|
+
formats,
|
|
428
|
+
seenAxisValuesByFontUrlAndAxisName,
|
|
429
|
+
instance = false
|
|
385
430
|
) {
|
|
386
431
|
const allFonts = [];
|
|
387
432
|
|
|
@@ -417,17 +462,35 @@ async function getSubsetsForFontUsage(
|
|
|
417
462
|
}, {});
|
|
418
463
|
|
|
419
464
|
const subsetPromiseMap = {};
|
|
465
|
+
const notFullyInstancedFontUrls = new Set();
|
|
420
466
|
|
|
421
467
|
for (const item of htmlOrSvgAssetTextsWithProps) {
|
|
422
468
|
for (const fontUsage of item.fontUsages) {
|
|
423
469
|
const fontBuffer = originalFontBuffers[fontUsage.fontUrl];
|
|
424
470
|
const text = fontUsage.text;
|
|
471
|
+
let variationAxes;
|
|
472
|
+
if (instance) {
|
|
473
|
+
variationAxes = await getFullyPinnedVariationAxes(
|
|
474
|
+
assetGraph,
|
|
475
|
+
fontUsage.fontUrl,
|
|
476
|
+
seenAxisValuesByFontUrlAndAxisName
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
if (!variationAxes) {
|
|
480
|
+
notFullyInstancedFontUrls.add(fontUsage.fontUrl);
|
|
481
|
+
}
|
|
482
|
+
|
|
425
483
|
for (const targetFormat of formats) {
|
|
426
|
-
const promiseId = getSubsetPromiseId(
|
|
484
|
+
const promiseId = getSubsetPromiseId(
|
|
485
|
+
fontUsage,
|
|
486
|
+
targetFormat,
|
|
487
|
+
variationAxes
|
|
488
|
+
);
|
|
427
489
|
|
|
428
490
|
if (!subsetPromiseMap[promiseId]) {
|
|
429
491
|
subsetPromiseMap[promiseId] = subsetFont(fontBuffer, text, {
|
|
430
492
|
targetFormat,
|
|
493
|
+
variationAxes,
|
|
431
494
|
}).catch((err) => {
|
|
432
495
|
const error = new Error(err.message);
|
|
433
496
|
error.asset = assetGraph.findAssets({
|
|
@@ -451,6 +514,7 @@ async function getSubsetsForFontUsage(
|
|
|
451
514
|
) {
|
|
452
515
|
fontUsage.smallestSubsetSize = size;
|
|
453
516
|
fontUsage.smallestSubsetFormat = targetFormat;
|
|
517
|
+
fontUsage.variationAxes = variationAxes;
|
|
454
518
|
}
|
|
455
519
|
}
|
|
456
520
|
});
|
|
@@ -459,6 +523,8 @@ async function getSubsetsForFontUsage(
|
|
|
459
523
|
}
|
|
460
524
|
|
|
461
525
|
await Promise.all(Object.values(subsetPromiseMap));
|
|
526
|
+
|
|
527
|
+
return { notFullyInstancedFontUrls };
|
|
462
528
|
}
|
|
463
529
|
|
|
464
530
|
const fontOrder = ['woff2', 'woff', 'truetype'];
|
|
@@ -605,7 +671,7 @@ async function createSelfHostedGoogleFontsCssAsset(
|
|
|
605
671
|
lines.push(` src: ${srcFragments.join(', ')};`);
|
|
606
672
|
lines.push(
|
|
607
673
|
` unicode-range: ${unicodeRange(
|
|
608
|
-
|
|
674
|
+
(await getFontInfo(cssFontFaceSrc.to.rawSrc)).characterSet
|
|
609
675
|
)};`
|
|
610
676
|
);
|
|
611
677
|
lines.push('}');
|
|
@@ -685,7 +751,10 @@ function parseFontStretchRange(str) {
|
|
|
685
751
|
return [minFontStretch, maxFontStretch];
|
|
686
752
|
}
|
|
687
753
|
|
|
688
|
-
function warnAboutMissingGlyphs(
|
|
754
|
+
async function warnAboutMissingGlyphs(
|
|
755
|
+
htmlOrSvgAssetTextsWithProps,
|
|
756
|
+
assetGraph
|
|
757
|
+
) {
|
|
689
758
|
const missingGlyphsErrors = [];
|
|
690
759
|
|
|
691
760
|
for (const {
|
|
@@ -695,9 +764,9 @@ function warnAboutMissingGlyphs(htmlOrSvgAssetTextsWithProps, assetGraph) {
|
|
|
695
764
|
} of htmlOrSvgAssetTextsWithProps) {
|
|
696
765
|
for (const fontUsage of fontUsages) {
|
|
697
766
|
if (fontUsage.subsets) {
|
|
698
|
-
const characterSet =
|
|
767
|
+
const { characterSet } = await getFontInfo(
|
|
699
768
|
Object.values(fontUsage.subsets)[0]
|
|
700
|
-
)
|
|
769
|
+
);
|
|
701
770
|
|
|
702
771
|
let missedAny = false;
|
|
703
772
|
for (const char of [...fontUsage.pageText]) {
|
|
@@ -788,10 +857,7 @@ function renderNumberRange(min, max) {
|
|
|
788
857
|
}
|
|
789
858
|
}
|
|
790
859
|
|
|
791
|
-
function
|
|
792
|
-
htmlOrSvgAssetTextsWithProps,
|
|
793
|
-
assetGraph
|
|
794
|
-
) {
|
|
860
|
+
function getVariationAxisUsage(htmlOrSvgAssetTextsWithProps) {
|
|
795
861
|
const seenAxisValuesByFontUrlAndAxisName = new Map();
|
|
796
862
|
const outOfBoundsAxesByFontUrl = new Map();
|
|
797
863
|
|
|
@@ -802,9 +868,9 @@ function warnAboutUnusedVariationAxes(
|
|
|
802
868
|
seenAxisValuesByFontUrlAndAxisName.set(fontUrl, seenAxes);
|
|
803
869
|
}
|
|
804
870
|
if (seenAxes.has(axisName)) {
|
|
805
|
-
seenAxes.get(axisName).
|
|
871
|
+
seenAxes.get(axisName).add(axisValue);
|
|
806
872
|
} else {
|
|
807
|
-
seenAxes.set(axisName, [axisValue]);
|
|
873
|
+
seenAxes.set(axisName, new Set([axisValue]));
|
|
808
874
|
}
|
|
809
875
|
}
|
|
810
876
|
|
|
@@ -877,23 +943,38 @@ function warnAboutUnusedVariationAxes(
|
|
|
877
943
|
}
|
|
878
944
|
}
|
|
879
945
|
|
|
946
|
+
return { seenAxisValuesByFontUrlAndAxisName, outOfBoundsAxesByFontUrl };
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
async function warnAboutUnusedVariationAxes(
|
|
950
|
+
assetGraph,
|
|
951
|
+
seenAxisValuesByFontUrlAndAxisName,
|
|
952
|
+
outOfBoundsAxesByFontUrl,
|
|
953
|
+
notFullyInstancedFontUrls
|
|
954
|
+
) {
|
|
880
955
|
const warnings = [];
|
|
881
956
|
for (const [
|
|
882
957
|
fontUrl,
|
|
883
958
|
seenAxisValuesByAxisName,
|
|
884
959
|
] of seenAxisValuesByFontUrlAndAxisName.entries()) {
|
|
960
|
+
if (!notFullyInstancedFontUrls.has(fontUrl)) {
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
885
963
|
const outOfBoundsAxes = outOfBoundsAxesByFontUrl.get(fontUrl) || new Set();
|
|
886
|
-
let
|
|
964
|
+
let fontInfo;
|
|
887
965
|
try {
|
|
888
|
-
|
|
966
|
+
fontInfo = await getFontInfo(
|
|
967
|
+
assetGraph.findAssets({ url: fontUrl })[0].rawSrc
|
|
968
|
+
);
|
|
889
969
|
} catch (err) {
|
|
890
|
-
// Don't break if we encounter an invalid font
|
|
970
|
+
// Don't break if we encounter an invalid font
|
|
891
971
|
continue;
|
|
892
972
|
}
|
|
973
|
+
|
|
893
974
|
const unusedAxes = [];
|
|
894
975
|
const underutilizedAxes = [];
|
|
895
976
|
for (const [name, { min, max, default: defaultValue }] of Object.entries(
|
|
896
|
-
|
|
977
|
+
fontInfo.variationAxes
|
|
897
978
|
)) {
|
|
898
979
|
if (ignoredVariationAxes.has(name)) {
|
|
899
980
|
continue;
|
|
@@ -1110,6 +1191,7 @@ async function subsetFonts(
|
|
|
1110
1191
|
formats = ['woff2', 'woff'],
|
|
1111
1192
|
subsetPath = 'subfont/',
|
|
1112
1193
|
omitFallbacks = false,
|
|
1194
|
+
instance = false,
|
|
1113
1195
|
inlineCss,
|
|
1114
1196
|
fontDisplay,
|
|
1115
1197
|
hrefType = 'rootRelative',
|
|
@@ -1203,7 +1285,8 @@ async function subsetFonts(
|
|
|
1203
1285
|
let originalCodepoints;
|
|
1204
1286
|
try {
|
|
1205
1287
|
// Guard against 'Unknown font format' errors
|
|
1206
|
-
originalCodepoints =
|
|
1288
|
+
originalCodepoints = (await getFontInfo(originalFont.rawSrc))
|
|
1289
|
+
.characterSet;
|
|
1207
1290
|
} catch (err) {}
|
|
1208
1291
|
if (originalCodepoints) {
|
|
1209
1292
|
const usedCodepoints = getCodepoints(fontUsage.text);
|
|
@@ -1233,15 +1316,25 @@ async function subsetFonts(
|
|
|
1233
1316
|
};
|
|
1234
1317
|
}
|
|
1235
1318
|
|
|
1319
|
+
const { seenAxisValuesByFontUrlAndAxisName, outOfBoundsAxesByFontUrl } =
|
|
1320
|
+
getVariationAxisUsage(htmlOrSvgAssetTextsWithProps);
|
|
1321
|
+
|
|
1236
1322
|
// Generate subsets:
|
|
1237
|
-
await getSubsetsForFontUsage(
|
|
1323
|
+
const { notFullyInstancedFontUrls } = await getSubsetsForFontUsage(
|
|
1238
1324
|
assetGraph,
|
|
1239
1325
|
htmlOrSvgAssetTextsWithProps,
|
|
1240
|
-
formats
|
|
1326
|
+
formats,
|
|
1327
|
+
seenAxisValuesByFontUrlAndAxisName,
|
|
1328
|
+
instance
|
|
1241
1329
|
);
|
|
1242
1330
|
|
|
1243
|
-
warnAboutMissingGlyphs(htmlOrSvgAssetTextsWithProps, assetGraph);
|
|
1244
|
-
warnAboutUnusedVariationAxes(
|
|
1331
|
+
await warnAboutMissingGlyphs(htmlOrSvgAssetTextsWithProps, assetGraph);
|
|
1332
|
+
await warnAboutUnusedVariationAxes(
|
|
1333
|
+
assetGraph,
|
|
1334
|
+
seenAxisValuesByFontUrlAndAxisName,
|
|
1335
|
+
outOfBoundsAxesByFontUrl,
|
|
1336
|
+
notFullyInstancedFontUrls
|
|
1337
|
+
);
|
|
1245
1338
|
|
|
1246
1339
|
// Insert subsets:
|
|
1247
1340
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subfont",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"description": "Speeds up your pages initial paint by automatically subsetting local or Google fonts and loading them optimally",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=10.0.0"
|
|
@@ -55,18 +55,18 @@
|
|
|
55
55
|
"css-list-helpers": "^2.0.0",
|
|
56
56
|
"font-snapper": "^1.2.0",
|
|
57
57
|
"font-tracer": "^3.6.0",
|
|
58
|
-
"fontkit": "^1.8.0",
|
|
59
58
|
"fontverter": "^2.0.0",
|
|
60
59
|
"gettemporaryfilepath": "^1.0.1",
|
|
60
|
+
"harfbuzzjs": "^0.3.3",
|
|
61
61
|
"lines-and-columns": "^1.1.6",
|
|
62
62
|
"lodash": "^4.17.15",
|
|
63
63
|
"memoizesync": "^1.1.1",
|
|
64
64
|
"postcss": "^8.3.11",
|
|
65
65
|
"postcss-value-parser": "^4.0.2",
|
|
66
66
|
"pretty-bytes": "^5.1.0",
|
|
67
|
-
"puppeteer-core": "^8.
|
|
67
|
+
"puppeteer-core": "^19.8.5",
|
|
68
68
|
"specificity": "^0.4.1",
|
|
69
|
-
"subset-font": "^1.
|
|
69
|
+
"subset-font": "^2.1.0",
|
|
70
70
|
"urltools": "^0.4.1",
|
|
71
71
|
"yargs": "^15.4.0"
|
|
72
72
|
},
|
|
@@ -90,11 +90,11 @@
|
|
|
90
90
|
"offline-github-changelog": "^1.6.1",
|
|
91
91
|
"prettier": "~2.3.0",
|
|
92
92
|
"proxyquire": "^2.1.1",
|
|
93
|
-
"puppeteer": "^8.
|
|
93
|
+
"puppeteer": "^19.8.5",
|
|
94
94
|
"sinon": "^9.0.2",
|
|
95
95
|
"unexpected": "^11.8.1",
|
|
96
96
|
"unexpected-check": "^2.3.1",
|
|
97
|
-
"unexpected-resemble": "^
|
|
97
|
+
"unexpected-resemble": "^5.0.1",
|
|
98
98
|
"unexpected-set": "^2.0.1",
|
|
99
99
|
"unexpected-sinon": "^10.11.2"
|
|
100
100
|
}
|