diff --git a/lib/subsetFonts.js b/lib/subsetFonts.js index 4a325ec4..f6fc6f35 100644 --- a/lib/subsetFonts.js +++ b/lib/subsetFonts.js @@ -776,8 +776,9 @@ These glyphs are used on your site, but they don't exist in the font you applied } const standardVariationAxes = new Set(['wght', 'wdth', 'ital', 'slnt', 'opsz']); -// Tracing the ranges of these standard axes require a bit more work, so just skip them for now: -const ignoredVariationAxes = new Set(['slnt', 'opsz']); +// It would be very hard to trace statically which values of opsz (font-optical-sizing) +// are going to be used, so we ignore that one: +const ignoredVariationAxes = new Set(['opsz']); function renderNumberRange(min, max) { if (min === max) { @@ -825,6 +826,25 @@ function warnAboutUnusedVariationAxes( seenAxes.set('ital', seenItalValues); } } + const seenSlntValues = []; + if (fontStyles.has('oblique')) { + // https://www.w3.org/TR/css-fonts-4/#font-style-prop + // oblique ? + // [...] The lack of an represents 14deg. + seenSlntValues.push(14); + } + // If any font-style value except oblique is seen (including normal or italic) + // we're also utilizing value 0: + if (fontStyles.size > fontStyles.has('oblique') ? 1 : 0) { + seenSlntValues.push(0); + } + if (seenSlntValues.length > 0) { + if (seenAxes.has('slnt')) { + seenAxes.get('slnt').push(...seenSlntValues); + } else { + seenAxes.set('slnt', seenSlntValues); + } + } const minMaxFontWeight = parseFontWeightRange(props['font-weight']); const seenFontWeightValues = []; diff --git a/test/subsetFonts.js b/test/subsetFonts.js index c59c8003..999f96a8 100644 --- a/test/subsetFonts.js +++ b/test/subsetFonts.js @@ -2896,7 +2896,7 @@ describe('subsetFonts', function () { infoSpy({ message: expect.it( 'to contain', - 'RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf:\n Unused axes: wght, wdth, GRAD, XOPQ, YOPQ, YTLC, YTUC, YTDE, YTFI\n Underutilized axes:\n YTAS: 400-750 used (649-854 available)' + 'RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf:\n Unused axes: wght, wdth, GRAD, slnt, XOPQ, YOPQ, YTLC, YTUC, YTDE, YTFI\n Underutilized axes:\n YTAS: 400-750 used (649-854 available)' ), }); }); @@ -3024,6 +3024,86 @@ describe('subsetFonts', function () { }); }); + describe('for the slnt axis', function () { + describe('when only font-style: normal is used', function () { + it('should emit an info event', async function () { + const assetGraph = new AssetGraph({ + root: pathModule.resolve( + __dirname, + '../testdata/subsetFonts/variable-font-unused-slnt-axis/' + ), + }); + await assetGraph.loadAssets('normal.html'); + await assetGraph.populate(); + const infoSpy = sinon.spy().named('info'); + assetGraph.on('info', infoSpy); + + await subsetFonts(assetGraph); + + expect(infoSpy, 'to have calls satisfying', function () { + infoSpy({ + message: expect.it( + 'to contain', + 'Unused axes: wght, wdth, GRAD, slnt, XTRA, XOPQ, YOPQ, YTLC, YTUC, YTAS, YTDE, YTFI' + ), + }); + }); + }); + }); + + describe('when only font-style: oblique is used', function () { + it('should emit an info event', async function () { + const assetGraph = new AssetGraph({ + root: pathModule.resolve( + __dirname, + '../testdata/subsetFonts/variable-font-unused-slnt-axis/' + ), + }); + await assetGraph.loadAssets('oblique.html'); + await assetGraph.populate(); + const infoSpy = sinon.spy().named('info'); + assetGraph.on('info', infoSpy); + + await subsetFonts(assetGraph); + + expect(infoSpy, 'to have calls satisfying', function () { + infoSpy({ + message: expect.it( + 'to contain', + 'Underutilized axes:\n slnt: 14 used (-10-0 available)' + ), + }); + }); + }); + }); + + describe('when both font-style: normal and font-style: oblique are used', function () { + it('should emit an info event', async function () { + const assetGraph = new AssetGraph({ + root: pathModule.resolve( + __dirname, + '../testdata/subsetFonts/variable-font-unused-slnt-axis/' + ), + }); + await assetGraph.loadAssets('normal_and_oblique.html'); + await assetGraph.populate(); + const infoSpy = sinon.spy().named('info'); + assetGraph.on('info', infoSpy); + + await subsetFonts(assetGraph); + + expect(infoSpy, 'to have calls satisfying', function () { + infoSpy({ + message: expect.it( + 'to contain', + 'Underutilized axes:\n slnt: 0-14 used (-10-0 available)' + ), + }); + }); + }); + }); + }); + describe('being animated with a cubic-bezier timing function', function () { describe('that stays within bounds', function () { it('should inform about the axis being underutilized', async function () { diff --git a/testdata/subsetFonts/variable-font-unused-slnt-axis/RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf b/testdata/subsetFonts/variable-font-unused-slnt-axis/RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf new file mode 100644 index 00000000..4cf1ecbf Binary files /dev/null and b/testdata/subsetFonts/variable-font-unused-slnt-axis/RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf differ diff --git a/testdata/subsetFonts/variable-font-unused-slnt-axis/normal.html b/testdata/subsetFonts/variable-font-unused-slnt-axis/normal.html new file mode 100644 index 00000000..fb5dc62f --- /dev/null +++ b/testdata/subsetFonts/variable-font-unused-slnt-axis/normal.html @@ -0,0 +1,16 @@ + + + + + + + +

Hello, world!

+ + diff --git a/testdata/subsetFonts/variable-font-unused-slnt-axis/normal_and_oblique.html b/testdata/subsetFonts/variable-font-unused-slnt-axis/normal_and_oblique.html new file mode 100644 index 00000000..2125f41c --- /dev/null +++ b/testdata/subsetFonts/variable-font-unused-slnt-axis/normal_and_oblique.html @@ -0,0 +1,21 @@ + + + + + + + +

Hello, world!

+

Hello, world!

+ + diff --git a/testdata/subsetFonts/variable-font-unused-slnt-axis/oblique.html b/testdata/subsetFonts/variable-font-unused-slnt-axis/oblique.html new file mode 100644 index 00000000..06f3f3e8 --- /dev/null +++ b/testdata/subsetFonts/variable-font-unused-slnt-axis/oblique.html @@ -0,0 +1,16 @@ + + + + + + + +

Hello, world!

+ + diff --git a/testdata/subsetFonts/variable-font-unused-slnt-axis/styles.css b/testdata/subsetFonts/variable-font-unused-slnt-axis/styles.css new file mode 100644 index 00000000..25dd3990 --- /dev/null +++ b/testdata/subsetFonts/variable-font-unused-slnt-axis/styles.css @@ -0,0 +1,5 @@ +@font-face { + font-family: MyFontFamily; + src: url('RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf') + format('woff2-variations'); +}