subsetFont method
Calls font-subset, which transforms the font to a
subsetted version at outputPath.
If the relative path is not recognized as an icon font used in the Flutter application, this returns false. If the font-subset subprocess fails, it will throw. Otherwise, it will return true.
Implementation
Future<FontAsset?> subsetFont({
required FontAsset font,
required String outputPath,
}) async {
final input = File.fromUri(font.file);
if (input.lengthSync() < 12) {
return null;
}
final mimeType = mime.lookupMimeType(
input.path,
headerBytes: await input.openRead(0, 12).first,
);
if (!kTtfMimeTypes.contains(mimeType)) {
return null;
}
await (_iconDataProcessing ??= _getIconData());
assert(_iconData != null);
final iconTreeShakerData = _iconData![font.file.path];
if (iconTreeShakerData == null) {
return null;
}
if (!fontSubset.existsSync()) {
throw IconTreeShakerException._(
'The font-subset utility is missing. Run "flutter doctor".',
);
}
final args = <String>[outputPath, input.path];
final requiredCodePointStrings = iconTreeShakerData.codePoints.map(
(int codePoint) => codePoint.toString(),
);
final optionalCodePointStrings = iconTreeShakerData.optionalCodePoints.map(
(int codePoint) => 'optional:$codePoint',
);
final codePointsString = requiredCodePointStrings
.followedBy(optionalCodePointStrings)
.join(' ');
print(
'Running font-subset: ${fontSubset.path} ${args.join(' ')}, '
'using codepoints $codePointsString',
);
final fontSubsetProcess = await Process.start(fontSubset.path, args);
try {
fontSubsetProcess.stdin.write(codePointsString);
await fontSubsetProcess.stdin.flush();
await fontSubsetProcess.stdin.close();
} on Exception {
// handled by checking the exit code.
}
final code = await fontSubsetProcess.exitCode;
if (code != 0) {
print(await utf8.decodeStream(fontSubsetProcess.stdout));
print(await utf8.decodeStream(fontSubsetProcess.stderr));
throw IconTreeShakerException._(
'Font subsetting failed with exit code $code.',
);
}
print(getSubsetSummaryMessage(input, File(outputPath)));
return FontAsset(
file: Uri.file(outputPath),
weight: font.weight,
family: font.family,
package: font.package,
);
}