Implement font fallback#187520
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds support for fallback font families in WebTextStyle and updates WebStrutStyle to apply styles using WebTextStyle. It also adds a test verifying fallback font rendering. Feedback on these changes highlights that unconditionally quoting the font family and bypassing canonicalizeFontFamily can break generic font families, and that fallback fonts themselves should be canonicalized. Additionally, the reviewer noted that fontFamilyFallback was omitted in WebStrutStyle's usage of WebTextStyle, and pointed out leftover commented-out code.
| List<String> get _fallbackFontFamilies { | ||
| if (isIOS15) { | ||
| // Remove the "-apple-system" fallback font because it causes a crash in | ||
| // iOS 15. | ||
| // | ||
| // See github issue: https://github.com/flutter/flutter/issues/90705 | ||
| // See webkit bug: https://bugs.webkit.org/show_bug.cgi?id=231686 | ||
| return <String>['BlinkMacSystemFont']; | ||
| } | ||
| if (isMacOrIOS) { | ||
| return <String>['-apple-system', 'BlinkMacSystemFont']; | ||
| } | ||
| return <String>['Arial']; | ||
| } | ||
|
|
||
| String _canonicalizeFontFamily(String? fontFamily, [List<String>? fontFamilyFallback]) { | ||
| final processedFontFamilyFallback = fontFamilyFallback == null || fontFamilyFallback.isEmpty | ||
| ? '' | ||
| : '${fontFamilyFallback.map(_processFontFamily).join(', ')}, '; | ||
| return '${_processFontFamily(fontFamily)}, $processedFontFamilyFallback ${_fallbackFontFamilies.join(', ')}, sans-serif'; | ||
| } | ||
|
|
||
| String? _processFontFamily(String? fontFamily) { | ||
| 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 _fallbackFontFamilies.join(', '); | ||
| } | ||
| } | ||
| return '"$fontFamily"'; | ||
| } |
There was a problem hiding this comment.
Is there a reason that requires duplicating this code here instead of refactoring the one in util.dart?
| String? get sharedFontFamily; | ||
| List<String>? get sharedFontFamilyFallback; | ||
| double? get sharedFontSize; | ||
| ui.FontWeight? get sharedFontWeight; | ||
| ui.FontStyle? get sharedFontStyle; | ||
| ui.Locale? get sharedLocale => null; | ||
| List<ui.FontFeature>? get sharedFontFeature => null; | ||
| List<ui.FontVariation>? get sharedFontVariations => null; | ||
| double? get sharedLetterSpacing => null; | ||
| double? get sharedWordSpacing => null; |
There was a problem hiding this comment.
Can we use the original property names instead of sharedXYZ?
Pass the correct font line to Canvas2D
I was only able to demonstrate it working on text fonts (Sans vs Serif).
Part of #172561