[web] Remap cupertino fonts to -apple-system (#18388)
* Remap cupertino fonts to -apple-system
* Update text tests for fallback checks
diff --git a/lib/web_ui/lib/src/engine/util.dart b/lib/web_ui/lib/src/engine/util.dart
index c410c8b..d0301e1 100644
--- a/lib/web_ui/lib/src/engine/util.dart
+++ b/lib/web_ui/lib/src/engine/util.dart
@@ -413,10 +413,18 @@
/// A default fallback font family in case an unloaded font has been requested.
///
-/// For iOS, default to Helvetica, where it should be available, otherwise
-/// default to Arial.
-final String _fallbackFontFamily =
- operatingSystem == OperatingSystem.iOs ? 'Helvetica' : 'Arial';
+/// -apple-system targets San Francisco in Safari (on Mac OS X and iOS),
+/// and it targets Neue Helvetica and Lucida Grande on older versions of
+/// Mac OS X. It properly selects between San Francisco Text and
+/// San Francisco Display depending on the text’s size.
+///
+/// For iOS, default to -apple-system, where it should be available, otherwise
+/// default to Arial. BlinkMacSystemFont is used for Chrome on iOS.
+final String _fallbackFontFamily = _isMacOrIOS ?
+ '-apple-system, BlinkMacSystemFont' : 'Arial';
+
+bool get _isMacOrIOS => operatingSystem == OperatingSystem.iOs ||
+ operatingSystem == OperatingSystem.macOs;
/// Create a font-family string appropriate for CSS.
///
@@ -426,6 +434,16 @@
if (_genericFontFamilies.contains(fontFamily)) {
return fontFamily;
}
+ if (_isMacOrIOS) {
+ // Unlike Safari, Chrome on iOS does not correctly fallback to cupertino
+ // on sans-serif.
+ // Map to San Francisco Text/Display fonts, use -apple-system,
+ // BlinkMacSystemFont.
+ if (fontFamily == '.SF Pro Text' || fontFamily == '.SF Pro Display' ||
+ fontFamily == '.SF UI Text' || fontFamily == '.SF UI Display') {
+ return _fallbackFontFamily;
+ }
+ }
return '"$fontFamily", $_fallbackFontFamily, sans-serif';
}
diff --git a/lib/web_ui/test/text_test.dart b/lib/web_ui/test/text_test.dart
index 0c9a5c6..266d88d 100644
--- a/lib/web_ui/test/text_test.dart
+++ b/lib/web_ui/test/text_test.dart
@@ -17,6 +17,16 @@
await webOnlyInitializeTestDomRenderer();
+ String fallback;
+ setUp(() {
+ if (operatingSystem == OperatingSystem.macOs ||
+ operatingSystem == OperatingSystem.iOs) {
+ fallback = '-apple-system, BlinkMacSystemFont';
+ } else {
+ fallback = 'Arial';
+ }
+ });
+
test('predictably lays out a single-line paragraph', () {
for (double fontSize in <double>[10.0, 20.0, 30.0, 40.0]) {
final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
@@ -361,9 +371,9 @@
expect(paragraph.plainText, isNull);
final List<SpanElement> spans =
paragraph.paragraphElement.querySelectorAll('span');
- expect(spans[0].style.fontFamily, 'Ahem, Arial, sans-serif');
+ expect(spans[0].style.fontFamily, 'Ahem, $fallback, sans-serif');
// The nested span here should not set it's family to default sans-serif.
- expect(spans[1].style.fontFamily, 'Ahem, Arial, sans-serif');
+ expect(spans[1].style.fontFamily, 'Ahem, $fallback, sans-serif');
},
// TODO(nurhan): https://github.com/flutter/flutter/issues/50771
// TODO(nurhan): https://github.com/flutter/flutter/issues/46638
@@ -383,7 +393,7 @@
final EngineParagraph paragraph = builder.build();
expect(paragraph.paragraphElement.style.fontFamily,
- 'SomeFont, Arial, sans-serif');
+ 'SomeFont, $fallback, sans-serif');
debugEmulateFlutterTesterEnvironment = true;
},
@@ -422,7 +432,7 @@
final EngineParagraph paragraph = builder.build();
expect(paragraph.paragraphElement.style.fontFamily,
- '"MyFont 2000", Arial, sans-serif');
+ '"MyFont 2000", $fallback, sans-serif');
debugEmulateFlutterTesterEnvironment = true;
},