diff --git a/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart b/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart index 91557e7b06bfc..7f3b0dee8bd56 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/icon_tree_shaker.dart @@ -138,15 +138,15 @@ class IconTreeShaker { if (codePoints == null) { throw IconTreeShakerException._('Expected to font code points for ${entry.key}, but none were found.'); } - if (_targetPlatform == TargetPlatform.web_javascript) { - if (!codePoints.contains(kSpacePoint)) { - codePoints.add(kSpacePoint); - } - } + + // Add space as an optional code point, as web uses it to measure the font height. + final List optionalCodePoints = _targetPlatform == TargetPlatform.web_javascript + ? [kSpacePoint] : []; result[entry.value] = _IconTreeShakerData( family: entry.key, relativePath: entry.value, codePoints: codePoints, + optionalCodePoints: optionalCodePoints, ); } _iconData = result; @@ -197,12 +197,17 @@ class IconTreeShaker { outputPath, input.path, ]; - final String codePoints = iconTreeShakerData.codePoints.join(' '); + final Iterable requiredCodePointStrings = iconTreeShakerData.codePoints + .map((int codePoint) => codePoint.toString()); + final Iterable optionalCodePointStrings = iconTreeShakerData.optionalCodePoints + .map((int codePoint) => 'optional:$codePoint'); + final String codePointsString = requiredCodePointStrings + .followedBy(optionalCodePointStrings).join(' '); _logger.printTrace('Running font-subset: ${cmd.join(' ')}, ' - 'using codepoints $codePoints'); + 'using codepoints $codePointsString'); final Process fontSubsetProcess = await _processManager.start(cmd); try { - fontSubsetProcess.stdin.writeln(codePoints); + fontSubsetProcess.stdin.writeln(codePointsString); await fontSubsetProcess.stdin.flush(); await fontSubsetProcess.stdin.close(); } on Exception { @@ -369,6 +374,7 @@ class _IconTreeShakerData { required this.family, required this.relativePath, required this.codePoints, + required this.optionalCodePoints, }); /// The font family name, e.g. "MaterialIcons". @@ -380,6 +386,10 @@ class _IconTreeShakerData { /// The list of code points for the font. final List codePoints; + /// The list of code points to be optionally added, if they exist in the + /// input font. Otherwise, the tool will silently omit them. + final List optionalCodePoints; + @override String toString() => 'FontSubsetData($family, $relativePath, $codePoints)'; } diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/icon_tree_shaker_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/icon_tree_shaker_test.dart index d786570798a1a..cb493e7cec765 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/icon_tree_shaker_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/icon_tree_shaker_test.dart @@ -411,7 +411,7 @@ void main() { expect(result, isTrue); final List codePoints = stdinSink.getAndClear().trim().split(whitespace); - expect(codePoints, isNot(contains('32'))); + expect(codePoints, isNot(contains('optional:32'))); expect(processManager, hasNoRemainingExpectations); }); @@ -456,7 +456,7 @@ void main() { expect(result, isTrue); final List codePoints = stdinSink.getAndClear().trim().split(whitespace); - expect(codePoints, containsAllInOrder(const ['59470', '32'])); + expect(codePoints, containsAllInOrder(const ['59470', 'optional:32'])); expect(processManager, hasNoRemainingExpectations); });