diff --git a/lib/web_ui/lib/src/engine/compositor/fonts.dart b/lib/web_ui/lib/src/engine/compositor/fonts.dart index 3c74dc49778e990142b3c45ad2d9bf2e21484945..9e40600d338a95a62ffdec4c725a93e925fbb195 100644 --- a/lib/web_ui/lib/src/engine/compositor/fonts.dart +++ b/lib/web_ui/lib/src/engine/compositor/fonts.dart @@ -4,9 +4,14 @@ part of engine; +const String _robotoUrl = + 'http://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Me5WZLCzYlKw.ttf'; + class SkiaFontCollection { final List> _loadingFontBuffers = >[]; + final Set registeredFamilies = {}; + Future ensureFontsLoaded() async { final List fontBuffers = (await Future.wait(_loadingFontBuffers)) @@ -46,6 +51,8 @@ class SkiaFontCollection { final String family = fontFamily['family']; final List fontAssets = fontFamily['fonts']; + registeredFamilies.add(family); + for (dynamic fontAssetItem in fontAssets) { final Map fontAsset = fontAssetItem; final String asset = fontAsset['asset']; @@ -54,6 +61,16 @@ class SkiaFontCollection { .then((dynamic fetchResult) => fetchResult.arrayBuffer())); } } + + /// We need a default fallback font for CanvasKit, in order to + /// avoid crashing while laying out text with an unregistered font. We chose + /// Roboto to match Android. + if (!registeredFamilies.contains('Roboto')) { + // Download Roboto and add it to the font buffers. + _loadingFontBuffers.add(html.window + .fetch(_robotoUrl) + .then((dynamic fetchResult) => fetchResult.arrayBuffer())); + } } js.JsObject skFontMgr; diff --git a/lib/web_ui/lib/src/engine/compositor/text.dart b/lib/web_ui/lib/src/engine/compositor/text.dart index f598c182f2cd3ab17de6ed58ec1aee8d49ff25ba..051c6ce06d6c475509228809813ef0af48e23fe1 100644 --- a/lib/web_ui/lib/src/engine/compositor/text.dart +++ b/lib/web_ui/lib/src/engine/compositor/text.dart @@ -9,17 +9,12 @@ part of engine; /// fonts. CanvasKit reads the font name from the font's bytes. So, we map /// some common family names to how they are registered in the Gallery app. const Map _fontFamilyOverrides = { - 'Roboto': 'Google Sans', 'GoogleSans': 'Google Sans', 'GoogleSansDisplay': 'Google Sans Display', 'MaterialIcons': 'Material Icons', - 'LibreFranklin': 'LibreFranklin', + 'LibreFranklin': 'Libre Franklin', 'AbrilFatface': 'Abril Fatface', 'packages/cupertino_icons/CupertinoIcons': 'CupertinoIcons', - '.SF Pro Text': 'Google Sans', - '.SF Pro Display': 'Google Sans', - '.SF UI Text': 'Google Sans', - '.SF UI Display': 'Google Sans', }; class SkParagraphStyle implements ui.ParagraphStyle { @@ -71,7 +66,8 @@ class SkParagraphStyle implements ui.ParagraphStyle { skTextStyle['fontSize'] = fontSize; } - if (fontFamily == null) { + if (fontFamily == null || + !skiaFontCollection.registeredFamilies.contains(fontFamily)) { fontFamily = 'Roboto'; } if (_fontFamilyOverrides.containsKey(fontFamily)) { @@ -205,7 +201,8 @@ class SkTextStyle implements ui.TextStyle { style['fontSize'] = fontSize; } - if (fontFamily == null) { + if (fontFamily == null || + !skiaFontCollection.registeredFamilies.contains(fontFamily)) { fontFamily = 'Roboto'; }