Skip to content

Commit

Permalink
Support reducing the variation space of individual axes (partial inst…
Browse files Browse the repository at this point in the history
…ancing)
  • Loading branch information
papandreou committed Mar 24, 2024
1 parent 8118084 commit 7937adb
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 6 deletions.
52 changes: 46 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,52 @@ async function subsetFont(

if (variationAxes) {
for (const [axisName, value] of Object.entries(variationAxes)) {
exports.hb_subset_input_pin_axis_location(
input,
face,
HB_TAG(axisName),
value
);
if (typeof value === 'number') {
// Simple case: Pin/instance the variation axis to a single value
if (
!exports.hb_subset_input_pin_axis_location(
input,
face,
HB_TAG(axisName),
value
)
) {
exports.hb_face_destroy(face);
exports.free(fontBuffer);
throw new Error(
`hb_subset_input_pin_axis_location (harfbuzz) returned zero when pinning ${axisName} and a value of ${value}, indicating failure.`
);
}
} else if (value && typeof value === 'object') {
// Complex case: Reduce the variation space of the axis
if (
typeof value.min === 'undefined' ||
typeof value.max === 'undefined'
) {
exports.hb_face_destroy(face);
exports.free(fontBuffer);
throw new Error(
`${axisName}: You must provide both a min and a max value when setting the axis range`
);
}
if (
!exports.hb_subset_input_set_axis_range(
input,
face,
HB_TAG(axisName),
value.min,
value.max,
// An explicit NaN makes harfbuzz use the existing default value, clamping to the new range if necessary
value.default ?? NaN
)
) {
exports.hb_face_destroy(face);
exports.free(fontBuffer);
throw new Error(
`hb_subset_input_set_axis_range (harfbuzz) returned zero when setting the range of ${axisName} to [${min}; ${max}] and a default value of ${defaultValue}, indicating failure.`

Check failure on line 129 in index.js

View workflow job for this annotation

GitHub Actions / Lint

'min' is not defined

Check failure on line 129 in index.js

View workflow job for this annotation

GitHub Actions / Lint

'max' is not defined

Check failure on line 129 in index.js

View workflow job for this annotation

GitHub Actions / Lint

'defaultValue' is not defined

Check failure on line 129 in index.js

View workflow job for this annotation

GitHub Actions / Lint

'min' is not defined

Check failure on line 129 in index.js

View workflow job for this annotation

GitHub Actions / Lint

'max' is not defined

Check failure on line 129 in index.js

View workflow job for this annotation

GitHub Actions / Lint

'defaultValue' is not defined
);
}
}
}
}

Expand Down
36 changes: 36 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,42 @@ describe('subset-font', function () {
slnt: { name: 'slnt', min: -10, default: 0, max: 0 },
});

// When not instancing the subset font is about 29 KB
expect(result.length, 'to be less than', 26000);
});
});

describe('when reducing the ranges of some variation axes', function () {
it('should perform a partial instancing', async function () {
const result = await subsetFont(this.variableRobotoFont, 'abcd', {
variationAxes: {
GRAD: { min: -50, max: 50, default: 25 },
slnt: { min: -9, max: 0 },
YTDE: { min: -100, max: -98 },
opsz: 14,
XTRA: 468,
XOPQ: 96,
YOPQ: 79,
YTLC: 514,
YTUC: 712,
YTAS: 750,
YTFI: 738,
// Leaving out wght and wdth so that the full variation space is preserved
},
});

expect(
fontkit.create(result).variationAxes,
'to exhaustively satisfy',
{
GRAD: { name: 'GRAD', min: -50, max: 50, default: 25 },
slnt: { name: 'slnt', min: -9, max: 0, default: 0 },
YTDE: { name: 'YTDE', min: -100, max: -98, default: -100 },
wght: { name: 'wght', min: 100, max: 1000, default: 400 },
wdth: { name: 'wdth', min: 25, max: 151, default: 100 },
}
);

// When not instancing the subset font is about 29 KB
expect(result.length, 'to be less than', 25000);
});
Expand Down

0 comments on commit 7937adb

Please sign in to comment.