From 40eeec263efab380d9e29b4436633359dca484b7 Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Mon, 17 Oct 2022 13:52:25 -0700 Subject: [PATCH 1/9] download fonts concurrently with wasm --- .../lib/src/engine/canvaskit/fonts.dart | 58 ++++++++++++++----- lib/web_ui/lib/src/engine/fonts.dart | 1 + lib/web_ui/lib/src/engine/initialization.dart | 6 +- .../lib/src/engine/text/font_collection.dart | 5 ++ 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart index 645407b03ac69..0f5bbb80533c2 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; @@ -36,6 +37,12 @@ class SkiaFontCollection implements FontCollection { /// happens after [ensureFontsLoaded] completes. final List _downloadedFonts = []; + /// Font ByteBuffer information and corresponding url and family are + /// temporarily stored here while waiting for canvaskit field to be initialized. + final List> _pendingFontInfo = List>.empty( + growable: true + ); + /// Returns fonts that have been downloaded and parsed. /// /// This should only be used in tests. @@ -141,7 +148,7 @@ class SkiaFontCollection implements FontCollection { for (final dynamic fontAssetItem in fontAssets) { final Map fontAsset = fontAssetItem as Map; final String asset = fontAsset.readString('asset'); - _registerFont(assetManager.getAssetUrl(asset), family); + unawaited(_registerFont(assetManager.getAssetUrl(asset), family)); } } @@ -150,10 +157,38 @@ class SkiaFontCollection implements FontCollection { /// Roboto to match Android. if (!_isFontFamilyRegistered('Roboto')) { // Download Roboto and add it to the font buffers. - _registerFont(_robotoUrl, 'Roboto'); + unawaited(_registerFont(_robotoUrl, 'Roboto')); } } + /// Make typefaces for each font and if successful, adds them to pendingFonts + /// to be resolved in _loadFonts. + @override + Future addPendingFonts() async { + Future addFont(ByteBuffer buffer, String url, String family) async { + final Uint8List bytes = buffer.asUint8List(); + final SkTypeface? typeface = + canvasKit.Typeface.MakeFreeTypeFaceFromData(bytes.buffer); + if (typeface != null) { + return RegisteredFont(bytes, family, typeface); + } else { + printWarning('Failed to load font $family at $url'); + printWarning('Verify that $url contains a valid font.'); + return null; + } + } + + for (final List fontInfo in _pendingFontInfo) { + final ByteBuffer buffer = fontInfo[0] as ByteBuffer; + final String url = fontInfo[1] as String; + final String family = fontInfo[2] as String; + if (buffer != null) { + _pendingFonts.add(addFont(buffer, url, family)); + } + } + _pendingFontInfo.clear(); + } + /// Whether the [fontFamily] was registered and/or loaded. bool _isFontFamilyRegistered(String fontFamily) { return _registeredFontFamilies.contains(fontFamily); @@ -182,31 +217,22 @@ class SkiaFontCollection implements FontCollection { FontFallbackData.instance.globalFontFallbacks.add(ahemFontFamily); } - void _registerFont(String url, String family) { - Future downloadFont() async { + Future _registerFont(String url, String family) async { + Future downloadFont() async { ByteBuffer buffer; try { buffer = await httpFetch(url).then(_getArrayBuffer); + return buffer; } catch (e) { printWarning('Failed to load font $family at $url'); printWarning(e.toString()); return null; } - - final Uint8List bytes = buffer.asUint8List(); - final SkTypeface? typeface = - canvasKit.Typeface.MakeFreeTypeFaceFromData(bytes.buffer); - if (typeface != null) { - return RegisteredFont(bytes, family, typeface); - } else { - printWarning('Failed to load font $family at $url'); - printWarning('Verify that $url contains a valid font.'); - return null; - } } _registeredFontFamilies.add(family); - _pendingFonts.add(downloadFont()); + final ByteBuffer? finishedLoadedFont = await downloadFont(); + _pendingFontInfo.add([finishedLoadedFont, url, family]); } diff --git a/lib/web_ui/lib/src/engine/fonts.dart b/lib/web_ui/lib/src/engine/fonts.dart index 0dd6c816c8357..2767cf07269ab 100644 --- a/lib/web_ui/lib/src/engine/fonts.dart +++ b/lib/web_ui/lib/src/engine/fonts.dart @@ -10,6 +10,7 @@ abstract class FontCollection { Future loadFontFromList(Uint8List list, {String? fontFamily}); Future ensureFontsLoaded(); Future registerFonts(AssetManager assetManager); + Future addPendingFonts(); void debugRegisterTestFonts(); void clear(); } diff --git a/lib/web_ui/lib/src/engine/initialization.dart b/lib/web_ui/lib/src/engine/initialization.dart index 00ecdd3ac1ee6..199312ed9f31c 100644 --- a/lib/web_ui/lib/src/engine/initialization.dart +++ b/lib/web_ui/lib/src/engine/initialization.dart @@ -204,10 +204,10 @@ Future initializeEngineServices({ } }; - await renderer.initialize(); - assetManager ??= const AssetManager(); - await _setAssetManager(assetManager); + Future rendererCallback () async => renderer.initialize(); + await Future.wait(>[rendererCallback(), _setAssetManager(assetManager)]); + await renderer.fontCollection.addPendingFonts(); await renderer.fontCollection.ensureFontsLoaded(); _initializationState = DebugEngineInitializationState.initializedServices; } diff --git a/lib/web_ui/lib/src/engine/text/font_collection.dart b/lib/web_ui/lib/src/engine/text/font_collection.dart index f66aa77245038..b308972db5b04 100644 --- a/lib/web_ui/lib/src/engine/text/font_collection.dart +++ b/lib/web_ui/lib/src/engine/text/font_collection.dart @@ -110,6 +110,11 @@ class HtmlFontCollection implements FontCollection { domDocument.fonts!.clear(); } } + + @override + Future addPendingFonts() async { + return; + } } /// Manages a collection of fonts and ensures they are loaded. From 347acef1da47557e5cca8cdc7f07eedd032ac8ce Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Fri, 21 Oct 2022 14:44:29 -0700 Subject: [PATCH 2/9] refactored fonts collection and affected tests --- .../src/engine/canvaskit/font_fallbacks.dart | 7 +- .../lib/src/engine/canvaskit/fonts.dart | 144 +++++++++--------- lib/web_ui/lib/src/engine/fonts.dart | 8 +- lib/web_ui/lib/src/engine/initialization.dart | 17 ++- .../lib/src/engine/text/font_collection.dart | 88 ++++++----- .../test/canvaskit/canvaskit_api_test.dart | 4 +- .../canvaskit/skia_font_collection_test.dart | 41 +++-- .../test/engine/image_to_byte_data_test.dart | 4 +- .../html/canvas_clip_path_golden_test.dart | 4 +- .../test/html/canvas_context_golden_test.dart | 4 +- .../test/html/canvas_reuse_golden_test.dart | 4 +- .../backdrop_filter_golden_test.dart | 4 +- .../compositing/canvas_blend_golden_test.dart | 4 +- .../canvas_image_blend_mode_golden_test.dart | 4 +- .../canvas_mask_filter_golden_test.dart | 4 +- .../compositing/color_filter_golden_test.dart | 4 +- .../compositing/compositing_golden_test.dart | 4 +- .../dom_mask_filter_golden_test.dart | 4 +- .../canvas_draw_color_golden_test.dart | 4 +- .../canvas_draw_picture_golden_test.dart | 4 +- .../drawing/draw_vertices_golden_test.dart | 4 +- .../test/html/path_metrics_golden_test.dart | 4 +- .../test/html/path_transform_golden_test.dart | 4 +- lib/web_ui/test/html/screenshot.dart | 4 +- .../shaders/image_shader_golden_test.dart | 4 +- .../shaders/linear_gradient_golden_test.dart | 4 +- .../shaders/radial_gradient_golden_test.dart | 4 +- .../html/shaders/shader_mask_golden_test.dart | 4 +- .../test/text/font_collection_test.dart | 35 +++-- 29 files changed, 231 insertions(+), 197 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/font_fallbacks.dart b/lib/web_ui/lib/src/engine/canvaskit/font_fallbacks.dart index 0cbc7ea3a790c..3491a43261208 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/font_fallbacks.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/font_fallbacks.dart @@ -447,12 +447,7 @@ class FallbackFontDownloadQueue { final Uint8List bytes = downloadedData[url]!; FontFallbackData.instance.registerFallbackFont(font.name, bytes); if (pendingFonts.isEmpty) { - _fontsLoading = renderer.fontCollection.ensureFontsLoaded(); - try { - await _fontsLoading; - } finally { - _fontsLoading = null; - } + renderer.fontCollection.registerDownloadedFonts(); sendFontChangeMessage(); } } diff --git a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart index 0f5bbb80533c2..ef40719921678 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart @@ -23,42 +23,29 @@ const String _robotoUrl = /// Manages the fonts used in the Skia-based backend. class SkiaFontCollection implements FontCollection { - final Set _registeredFontFamilies = {}; + final Set _downloadedFontFamilies = {}; - /// Fonts that started the download process. + /// Fonts that started the download process, but are not yet registered. /// - /// Once downloaded successfully, this map is cleared and the resulting - /// [RegisteredFont]s are added to [_downloadedFonts]. - final List> _pendingFonts = >[]; + /// /// Once downloaded successfully, this map is cleared and the resulting + /// [UnregisteredFont]s are added to [_registeredFonts]. + final List _unregisteredFonts = []; - /// Fonts that have been downloaded and parsed into [SkTypeface]. - /// - /// These fonts may not yet have been registered with the [fontProvider]. This - /// happens after [ensureFontsLoaded] completes. - final List _downloadedFonts = []; - - /// Font ByteBuffer information and corresponding url and family are - /// temporarily stored here while waiting for canvaskit field to be initialized. - final List> _pendingFontInfo = List>.empty( - growable: true - ); + final List _registeredFonts = []; - /// Returns fonts that have been downloaded and parsed. + /// Returns fonts that have been downloaded, registered, and parsed. /// /// This should only be used in tests. - List? get debugDownloadedFonts { + List? get debugRegisteredFonts { if (!assertionsEnabled) { return null; } - return _downloadedFonts; + return _registeredFonts; } final Map> familyToFontMap = >{}; - @override - Future ensureFontsLoaded() async { - await _loadFonts(); - + void _registerWithFontProvider() { if (fontProvider != null) { fontProvider!.delete(); fontProvider = null; @@ -66,7 +53,7 @@ class SkiaFontCollection implements FontCollection { fontProvider = canvasKit.TypefaceFontProvider.Make(); familyToFontMap.clear(); - for (final RegisteredFont font in _downloadedFonts) { + for (final RegisteredFont font in _registeredFonts) { fontProvider!.registerFont(font.bytes, font.family); familyToFontMap .putIfAbsent(font.family, () => []) @@ -82,21 +69,6 @@ class SkiaFontCollection implements FontCollection { } } - /// Loads all of the unloaded fonts in [_pendingFonts] and adds them - /// to [_downloadedFonts]. - Future _loadFonts() async { - if (_pendingFonts.isEmpty) { - return; - } - final List loadedFonts = await Future.wait(_pendingFonts); - for (final RegisteredFont? font in loadedFonts) { - if (font != null) { - _downloadedFonts.add(font); - } - } - _pendingFonts.clear(); - } - @override Future loadFontFromList(Uint8List list, {String? fontFamily}) async { if (fontFamily == null) { @@ -110,8 +82,8 @@ class SkiaFontCollection implements FontCollection { final SkTypeface? typeface = canvasKit.Typeface.MakeFreeTypeFaceFromData(list.buffer); if (typeface != null) { - _downloadedFonts.add(RegisteredFont(list, fontFamily, typeface)); - await ensureFontsLoaded(); + _registeredFonts.add(RegisteredFont(list, fontFamily, typeface)); + registerDownloadedFonts(); } else { printWarning('Failed to parse font family "$fontFamily"'); return; @@ -120,7 +92,7 @@ class SkiaFontCollection implements FontCollection { /// Loads fonts from `FontManifest.json`. @override - Future registerFonts(AssetManager assetManager) async { + Future downloadAssetFonts(AssetManager assetManager) async { ByteData byteData; try { @@ -141,6 +113,8 @@ class SkiaFontCollection implements FontCollection { 'There was a problem trying to load FontManifest.json'); } + final List> pendingFonts = >[]; + for (final Map fontFamily in fontManifest.cast>()) { final String family = fontFamily.readString('family'); @@ -148,24 +122,25 @@ class SkiaFontCollection implements FontCollection { for (final dynamic fontAssetItem in fontAssets) { final Map fontAsset = fontAssetItem as Map; final String asset = fontAsset.readString('asset'); - unawaited(_registerFont(assetManager.getAssetUrl(asset), family)); + _downloadFont(pendingFonts, assetManager.getAssetUrl(asset), family); } } /// 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 (!_isFontFamilyRegistered('Roboto')) { + if (!_isFontFamilyDownloaded('Roboto')) { // Download Roboto and add it to the font buffers. - unawaited(_registerFont(_robotoUrl, 'Roboto')); + _downloadFont(pendingFonts, _robotoUrl, 'Roboto'); } + + final List completedPendingFonts = await Future.wait(pendingFonts); + _unregisteredFonts.addAll(completedPendingFonts.whereType()); } - /// Make typefaces for each font and if successful, adds them to pendingFonts - /// to be resolved in _loadFonts. @override - Future addPendingFonts() async { - Future addFont(ByteBuffer buffer, String url, String family) async { + void registerDownloadedFonts() { + RegisteredFont? makeRegisterFont(ByteBuffer buffer, String url, String family) { final Uint8List bytes = buffer.asUint8List(); final SkTypeface? typeface = canvasKit.Typeface.MakeFreeTypeFaceFromData(bytes.buffer); @@ -178,51 +153,67 @@ class SkiaFontCollection implements FontCollection { } } - for (final List fontInfo in _pendingFontInfo) { - final ByteBuffer buffer = fontInfo[0] as ByteBuffer; - final String url = fontInfo[1] as String; - final String family = fontInfo[2] as String; - if (buffer != null) { - _pendingFonts.add(addFont(buffer, url, family)); - } + if (_unregisteredFonts.isEmpty) { + return; + } + + for (final UnregisteredFont unregisteredFont in _unregisteredFonts) { + final RegisteredFont? registeredFont = makeRegisterFont( + unregisteredFont.bytes, + unregisteredFont.url, + unregisteredFont.family + ); + if (registeredFont != null) { + _registeredFonts.add(registeredFont); + } } - _pendingFontInfo.clear(); + + _unregisteredFonts.clear(); + _registerWithFontProvider(); } /// Whether the [fontFamily] was registered and/or loaded. - bool _isFontFamilyRegistered(String fontFamily) { - return _registeredFontFamilies.contains(fontFamily); + bool _isFontFamilyDownloaded(String fontFamily) { + return _downloadedFontFamilies.contains(fontFamily); } /// Loads the Ahem font, unless it's already been loaded using - /// `FontManifest.json` (see [registerFonts]). + /// `FontManifest.json` (see [downloadAssetFonts]). /// /// `FontManifest.json` has higher priority than the default test font URLs. /// This allows customizing test environments where fonts are loaded from /// different URLs. @override - void debugRegisterTestFonts() { - if (!_isFontFamilyRegistered(ahemFontFamily)) { - _registerFont(ahemFontUrl, ahemFontFamily); + Future debugDownloadTestFonts() async { + final List> pendingFonts = >[]; + if (!_isFontFamilyDownloaded(ahemFontFamily)) { + _downloadFont(pendingFonts, ahemFontUrl, ahemFontFamily); } - if (!_isFontFamilyRegistered(robotoFontFamily)) { - _registerFont(robotoTestFontUrl, robotoFontFamily); + if (!_isFontFamilyDownloaded(robotoFontFamily)) { + _downloadFont(pendingFonts, robotoTestFontUrl, robotoFontFamily); } - if (!_isFontFamilyRegistered(robotoVariableFontFamily)) { - _registerFont(robotoVariableTestFontUrl, robotoVariableFontFamily); + if (!_isFontFamilyDownloaded(robotoVariableFontFamily)) { + _downloadFont(pendingFonts, robotoVariableTestFontUrl, robotoVariableFontFamily); } + final List completedPendingFonts = await Future.wait(pendingFonts); + _unregisteredFonts.addAll(completedPendingFonts.whereType()); + // Ahem must be added to font fallbacks list regardless of where it was // downloaded from. FontFallbackData.instance.globalFontFallbacks.add(ahemFontFamily); } - Future _registerFont(String url, String family) async { - Future downloadFont() async { + void _downloadFont( + List> waitUnregisteredFonts, + String url, + String family + ) { + Future downloadFont() async { ByteBuffer buffer; try { buffer = await httpFetch(url).then(_getArrayBuffer); - return buffer; + return UnregisteredFont(buffer, url, family); } catch (e) { printWarning('Failed to load font $family at $url'); printWarning(e.toString()); @@ -230,9 +221,8 @@ class SkiaFontCollection implements FontCollection { } } - _registeredFontFamilies.add(family); - final ByteBuffer? finishedLoadedFont = await downloadFont(); - _pendingFontInfo.add([finishedLoadedFont, url, family]); + _downloadedFontFamilies.add(family); + waitUnregisteredFonts.add(downloadFont()); } @@ -275,3 +265,11 @@ class RegisteredFont { /// This is used to determine which code points are supported by this font. final SkTypeface typeface; } + +/// Represents a font that has been downloaded but not registered. +class UnregisteredFont { + const UnregisteredFont(this.bytes, this.url, this.family); + final ByteBuffer bytes; + final String url; + final String family; +} diff --git a/lib/web_ui/lib/src/engine/fonts.dart b/lib/web_ui/lib/src/engine/fonts.dart index 2767cf07269ab..39b607d18afc5 100644 --- a/lib/web_ui/lib/src/engine/fonts.dart +++ b/lib/web_ui/lib/src/engine/fonts.dart @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; import 'dart:typed_data'; import 'assets.dart'; abstract class FontCollection { Future loadFontFromList(Uint8List list, {String? fontFamily}); - Future ensureFontsLoaded(); - Future registerFonts(AssetManager assetManager); - Future addPendingFonts(); - void debugRegisterTestFonts(); + Future downloadAssetFonts(AssetManager assetManager); + void registerDownloadedFonts(); + FutureOr debugDownloadTestFonts(); void clear(); } diff --git a/lib/web_ui/lib/src/engine/initialization.dart b/lib/web_ui/lib/src/engine/initialization.dart index 199312ed9f31c..707c184327000 100644 --- a/lib/web_ui/lib/src/engine/initialization.dart +++ b/lib/web_ui/lib/src/engine/initialization.dart @@ -205,10 +205,11 @@ Future initializeEngineServices({ }; assetManager ??= const AssetManager(); - Future rendererCallback () async => renderer.initialize(); - await Future.wait(>[rendererCallback(), _setAssetManager(assetManager)]); - await renderer.fontCollection.addPendingFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + _setAssetManager(assetManager); + + Future initializeRendererCallback () async => renderer.initialize(); + await Future.wait(>[initializeRendererCallback(), _downloadAssetFonts(assetManager)]); + renderer.fontCollection.registerDownloadedFonts(); _initializationState = DebugEngineInitializationState.initializedServices; } @@ -243,22 +244,24 @@ Future initializeEngineUi() async { AssetManager get assetManager => _assetManager!; AssetManager? _assetManager; -Future _setAssetManager(AssetManager assetManager) async { +void _setAssetManager(AssetManager assetManager) { assert(assetManager != null, 'Cannot set assetManager to null'); if (assetManager == _assetManager) { return; } _assetManager = assetManager; +} +Future _downloadAssetFonts(AssetManager assetManager) async { renderer.fontCollection.clear(); if (_assetManager != null) { - await renderer.fontCollection.registerFonts(assetManager); + await renderer.fontCollection.downloadAssetFonts(assetManager); } if (ui.debugEmulateFlutterTesterEnvironment) { - renderer.fontCollection.debugRegisterTestFonts(); + await renderer.fontCollection.debugDownloadTestFonts(); } } diff --git a/lib/web_ui/lib/src/engine/text/font_collection.dart b/lib/web_ui/lib/src/engine/text/font_collection.dart index b308972db5b04..176fe24b80fca 100644 --- a/lib/web_ui/lib/src/engine/text/font_collection.dart +++ b/lib/web_ui/lib/src/engine/text/font_collection.dart @@ -17,17 +17,17 @@ import 'layout_service.dart'; /// This class is responsible for registering and loading fonts. /// /// Once an asset manager has been set in the framework, call -/// [registerFonts] with it to register fonts declared in the +/// [downloadAssetFonts] with it to register fonts declared in the /// font manifest. If test fonts are enabled, then call -/// [registerTestFonts] as well. +/// [debugDownloadTestFonts] as well. class HtmlFontCollection implements FontCollection { FontManager? _assetFontManager; FontManager? _testFontManager; - /// Reads the font manifest using the [assetManager] and registers all of the + /// Reads the font manifest using the [assetManager] and downloads all of the /// fonts declared within. @override - Future registerFonts(AssetManager assetManager) async { + Future downloadAssetFonts(AssetManager assetManager) async { ByteData byteData; try { @@ -67,10 +67,13 @@ class HtmlFontCollection implements FontCollection { descriptors[descriptor] = '${fontAsset[descriptor]}'; } } - _assetFontManager!.registerAsset( + _assetFontManager!.downloadAsset( family!, 'url(${assetManager.getAssetUrl(asset)})', descriptors); } } + + final List loadedFonts = await Future.wait(_assetFontManager!._fontLoadingFutures); + _assetFontManager!._downloadedFonts.addAll(loadedFonts.whereType()); } @override @@ -81,24 +84,24 @@ class HtmlFontCollection implements FontCollection { return _assetFontManager!._loadFontFaceBytes(fontFamily, list); } - /// Registers fonts that are used by tests. + /// Downloads fonts that are used by tests. @override - void debugRegisterTestFonts() { + Future debugDownloadTestFonts() async { _testFontManager = FontManager(); - _testFontManager!.registerAsset( + _testFontManager!.downloadAsset( ahemFontFamily, 'url($ahemFontUrl)', const {}); - _testFontManager!.registerAsset(robotoFontFamily, + _testFontManager!.downloadAsset(robotoFontFamily, 'url($robotoTestFontUrl)', const {}); - _testFontManager!.registerAsset(robotoVariableFontFamily, + _testFontManager!.downloadAsset(robotoVariableFontFamily, 'url($robotoVariableTestFontUrl)', const {}); + final List loadedFonts = await Future.wait(_testFontManager!._fontLoadingFutures); + _testFontManager!._downloadedFonts.addAll(loadedFonts.whereType()); } - /// Returns a [Future] that completes when the registered fonts are loaded - /// and ready to be used. @override - Future ensureFontsLoaded() async { - await _assetFontManager?.ensureFontsLoaded(); - await _testFontManager?.ensureFontsLoaded(); + void registerDownloadedFonts() { + _assetFontManager?.registerDownloadedFonts(); + _testFontManager?.registerDownloadedFonts(); } /// Unregister all fonts that have been registered. @@ -129,7 +132,12 @@ class FontManager { FontManager._(); - final List> _fontLoadingFutures = >[]; + /// Fonts that started the downloading process. Once the fonts have downloaded + /// without error, they are moved to [_downloadedFonts]. Those fonts + /// are subsequently registered by [registerDownloadedFonts]. + final List> _fontLoadingFutures = >[]; + + final List _downloadedFonts = []; // Regular expression to detect a string with no punctuations. // For example font family 'Ahem!' does not fall into this category @@ -172,7 +180,7 @@ class FontManager { /// /// * https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names /// * https://drafts.csswg.org/css-fonts-3/#font-family-prop - void registerAsset( + void downloadAsset( String family, String asset, Map descriptors, @@ -192,19 +200,40 @@ class FontManager { String asset, Map descriptors, ) { + Future fontFaceLoad(DomFontFace fontFace) async { + try { + return fontFace.load(); + } catch (e) { + printWarning('Error while trying to load font family "$family":\n$e'); + return null; + } + } // try/catch because `new FontFace` can crash with an improper font family. try { final DomFontFace fontFace = createDomFontFace(family, asset, descriptors); - _fontLoadingFutures.add(fontFace.load().then((_) { - domDocument.fonts!.add(fontFace); - }, onError: (dynamic e) { - printWarning('Error while trying to load font family "$family":\n$e'); - })); + _fontLoadingFutures.add(fontFaceLoad(fontFace)); } catch (e) { printWarning('Error while loading font family "$family":\n$e'); } } + void registerDownloadedFonts() { + if (_downloadedFonts.isEmpty) { + return; + } + + for (final DomFontFace? fontFace in _downloadedFonts) { + if (fontFace != null) { + domDocument.fonts!.add(fontFace); + } + } + } + + Future testFillDownloadedFonts() async { + final List loadedFonts = await Future.wait(_fontLoadingFutures); + _downloadedFonts.addAll(loadedFonts.whereType()); + } + // Loads a font from bytes, surfacing errors through the future. Future _loadFontFaceBytes(String family, Uint8List list) { // Since these fonts are loaded by user code, surface the error @@ -224,12 +253,6 @@ class FontManager { throw Exception(exception.toString()); }); } - - /// Returns a [Future] that completes when all fonts that have been - /// registered with this font manager have been loaded and are ready to use. - Future ensureFontsLoaded() { - return Future.wait(_fontLoadingFutures); - } } /// A font manager that works without using the CSS Font Loading API. @@ -247,7 +270,7 @@ class _PolyfillFontManager extends FontManager { static const Duration _fontLoadRetryDuration = Duration(milliseconds: 50); @override - void registerAsset( + void downloadAsset( String family, String asset, Map descriptors, @@ -271,18 +294,13 @@ class _PolyfillFontManager extends FontManager { paragraph.style.fontFamily = "'$family', $fallbackFontName"; - final Completer completer = Completer(); - late DateTime fontLoadStart; void watchWidth() { if (paragraph.offsetWidth != sansSerifWidth) { paragraph.remove(); - completer.complete(); } else { if (DateTime.now().difference(fontLoadStart) > _fontLoadTimeout) { - // Let application waiting for fonts continue with fallback. - completer.complete(); // Throw unhandled exception for logging. throw Exception('Timed out trying to load font: $family'); } else { @@ -318,7 +336,5 @@ class _PolyfillFontManager extends FontManager { fontLoadStart = DateTime.now(); watchWidth(); - - _fontLoadingFutures.add(completer.future); } } diff --git a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart index 91268881f2062..0bef47370b092 100644 --- a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart +++ b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart @@ -1465,8 +1465,8 @@ void _textStyleTests() { void _paragraphTests() { setUpAll(() async { - CanvasKitRenderer.instance.fontCollection.debugRegisterTestFonts(); - await CanvasKitRenderer.instance.fontCollection.ensureFontsLoaded(); + await CanvasKitRenderer.instance.fontCollection.debugDownloadTestFonts(); + CanvasKitRenderer.instance.fontCollection.registerDownloadedFonts(); }); // This test is just a kitchen sink that blasts CanvasKit with all paragraph diff --git a/lib/web_ui/test/canvaskit/skia_font_collection_test.dart b/lib/web_ui/test/canvaskit/skia_font_collection_test.dart index 9f6aac9a4c926..97668652c7fdf 100644 --- a/lib/web_ui/test/canvaskit/skia_font_collection_test.dart +++ b/lib/web_ui/test/canvaskit/skia_font_collection_test.dart @@ -35,12 +35,13 @@ void testMain() { warnings.clear(); }); - test('logs no warnings with the default mock asset manager', () { + test('logs no warnings with the default mock asset manager', () async { final SkiaFontCollection fontCollection = SkiaFontCollection(); final WebOnlyMockAssetManager mockAssetManager = WebOnlyMockAssetManager(); - expect(fontCollection.registerFonts(mockAssetManager), completes); - expect(fontCollection.ensureFontsLoaded(), completes); + await fontCollection.downloadAssetFonts(mockAssetManager); + fontCollection.registerDownloadedFonts(); + expect(warnings, isEmpty); }); @@ -61,8 +62,8 @@ void testMain() { ] '''; // It should complete without error, but emit a warning about BrokenFont. - await fontCollection.registerFonts(mockAssetManager); - await fontCollection.ensureFontsLoaded(); + await fontCollection.downloadAssetFonts(mockAssetManager); + fontCollection.registerDownloadedFonts(); expect( warnings, containsAllInOrder( @@ -89,13 +90,13 @@ void testMain() { final ByteBuffer robotoData = (await (await httpFetch('/assets/fonts/Roboto-Regular.ttf')).arrayBuffer())! as ByteBuffer; - await fontCollection.registerFonts(mockAssetManager); - fontCollection.debugRegisterTestFonts(); - await fontCollection.ensureFontsLoaded(); + await fontCollection.downloadAssetFonts(mockAssetManager); + await fontCollection.debugDownloadTestFonts(); + fontCollection.registerDownloadedFonts(); expect(warnings, isEmpty); // Use `singleWhere` to make sure only one version of 'Ahem' is loaded. - final RegisteredFont ahem = fontCollection.debugDownloadedFonts! + final RegisteredFont ahem = fontCollection.debugRegisteredFonts! .singleWhere((RegisteredFont font) => font.family == 'Ahem'); // Check that the contents of 'Ahem' is actually Roboto, because that's @@ -111,18 +112,32 @@ void testMain() { final ByteBuffer ahemData = (await (await httpFetch('/assets/fonts/ahem.ttf')).arrayBuffer())! as ByteBuffer; - await fontCollection.registerFonts(mockAssetManager); - fontCollection.debugRegisterTestFonts(); - await fontCollection.ensureFontsLoaded(); + await fontCollection.downloadAssetFonts(mockAssetManager); + await fontCollection.debugDownloadTestFonts(); + fontCollection.registerDownloadedFonts(); expect(warnings, isEmpty); // Use `singleWhere` to make sure only one version of 'Ahem' is loaded. - final RegisteredFont ahem = fontCollection.debugDownloadedFonts! + final RegisteredFont ahem = fontCollection.debugRegisteredFonts! .singleWhere((RegisteredFont font) => font.family == 'Ahem'); // Check that the contents of 'Ahem' is actually Roboto, because that's // what's specified in the manifest, and the manifest takes precedence. expect(ahem.bytes.length, ahemData.lengthInBytes); }); + + test('download fonts separately from registering', () async { + final SkiaFontCollection fontCollection = SkiaFontCollection(); + + await fontCollection.debugDownloadTestFonts(); + /// Fonts should have been downloaded, but not yet registered + expect(fontCollection.debugRegisteredFonts, isEmpty); + + fontCollection.registerDownloadedFonts(); + /// Fonts should now be registered and _registeredFonts should be filled + expect(fontCollection.debugRegisteredFonts, isNotEmpty); + expect(warnings, isEmpty); + + }); }); } diff --git a/lib/web_ui/test/engine/image_to_byte_data_test.dart b/lib/web_ui/test/engine/image_to_byte_data_test.dart index 991c3e80c8853..a9bb8a791f2ea 100644 --- a/lib/web_ui/test/engine/image_to_byte_data_test.dart +++ b/lib/web_ui/test/engine/image_to_byte_data_test.dart @@ -16,8 +16,8 @@ void main() { Future testMain() async { setUpAll(() async { await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); Future createTestImageByColor(Color color) async { diff --git a/lib/web_ui/test/html/canvas_clip_path_golden_test.dart b/lib/web_ui/test/html/canvas_clip_path_golden_test.dart index 6e359a59bdfee..a4643c3a97359 100644 --- a/lib/web_ui/test/html/canvas_clip_path_golden_test.dart +++ b/lib/web_ui/test/html/canvas_clip_path_golden_test.dart @@ -19,8 +19,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - engine.renderer.fontCollection.debugRegisterTestFonts(); - await engine.renderer.fontCollection.ensureFontsLoaded(); + await engine.renderer.fontCollection.debugDownloadTestFonts(); + engine.renderer.fontCollection.registerDownloadedFonts(); }); // Regression test for https://github.com/flutter/flutter/issues/48683 diff --git a/lib/web_ui/test/html/canvas_context_golden_test.dart b/lib/web_ui/test/html/canvas_context_golden_test.dart index eb78daf3e7e50..53a9d30a2e201 100644 --- a/lib/web_ui/test/html/canvas_context_golden_test.dart +++ b/lib/web_ui/test/html/canvas_context_golden_test.dart @@ -22,8 +22,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - engine.renderer.fontCollection.debugRegisterTestFonts(); - await engine.renderer.fontCollection.ensureFontsLoaded(); + await engine.renderer.fontCollection.debugDownloadTestFonts(); + engine.renderer.fontCollection.registerDownloadedFonts(); }); // Regression test for https://github.com/flutter/flutter/issues/49429 diff --git a/lib/web_ui/test/html/canvas_reuse_golden_test.dart b/lib/web_ui/test/html/canvas_reuse_golden_test.dart index b0b3b6606d81b..0757f0851e879 100644 --- a/lib/web_ui/test/html/canvas_reuse_golden_test.dart +++ b/lib/web_ui/test/html/canvas_reuse_golden_test.dart @@ -25,8 +25,8 @@ Future testMain() async { setUp(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); // Regression test for https://github.com/flutter/flutter/issues/51514 diff --git a/lib/web_ui/test/html/compositing/backdrop_filter_golden_test.dart b/lib/web_ui/test/html/compositing/backdrop_filter_golden_test.dart index 734f26f308221..402441b9bb1f6 100644 --- a/lib/web_ui/test/html/compositing/backdrop_filter_golden_test.dart +++ b/lib/web_ui/test/html/compositing/backdrop_filter_golden_test.dart @@ -16,8 +16,8 @@ void main() { Future testMain() async { setUpAll(() async { await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); setUp(() async { diff --git a/lib/web_ui/test/html/compositing/canvas_blend_golden_test.dart b/lib/web_ui/test/html/compositing/canvas_blend_golden_test.dart index 537e476059c6a..b1851aa4e51b6 100644 --- a/lib/web_ui/test/html/compositing/canvas_blend_golden_test.dart +++ b/lib/web_ui/test/html/compositing/canvas_blend_golden_test.dart @@ -20,8 +20,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); test('Blend circles with difference and color', () async { diff --git a/lib/web_ui/test/html/compositing/canvas_image_blend_mode_golden_test.dart b/lib/web_ui/test/html/compositing/canvas_image_blend_mode_golden_test.dart index 6883fff2d34cf..a4ad2e240ecb3 100644 --- a/lib/web_ui/test/html/compositing/canvas_image_blend_mode_golden_test.dart +++ b/lib/web_ui/test/html/compositing/canvas_image_blend_mode_golden_test.dart @@ -20,8 +20,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); const Color red = Color(0xFFFF0000); diff --git a/lib/web_ui/test/html/compositing/canvas_mask_filter_golden_test.dart b/lib/web_ui/test/html/compositing/canvas_mask_filter_golden_test.dart index 24ab2bf8156c6..03e8b8d2ccf5b 100644 --- a/lib/web_ui/test/html/compositing/canvas_mask_filter_golden_test.dart +++ b/lib/web_ui/test/html/compositing/canvas_mask_filter_golden_test.dart @@ -20,8 +20,8 @@ Future testMain() async { setUpAll(() async { ui.debugEmulateFlutterTesterEnvironment = true; await ui.webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); tearDown(() { diff --git a/lib/web_ui/test/html/compositing/color_filter_golden_test.dart b/lib/web_ui/test/html/compositing/color_filter_golden_test.dart index 9d57be6d665b6..3da07d2fc5ccc 100644 --- a/lib/web_ui/test/html/compositing/color_filter_golden_test.dart +++ b/lib/web_ui/test/html/compositing/color_filter_golden_test.dart @@ -20,8 +20,8 @@ void main() { Future testMain() async { setUpAll(() async { await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); setUp(() async { diff --git a/lib/web_ui/test/html/compositing/compositing_golden_test.dart b/lib/web_ui/test/html/compositing/compositing_golden_test.dart index 7856d063b84b1..5d237cd09b6f5 100644 --- a/lib/web_ui/test/html/compositing/compositing_golden_test.dart +++ b/lib/web_ui/test/html/compositing/compositing_golden_test.dart @@ -21,8 +21,8 @@ void main() { Future testMain() async { setUpAll(() async { await ui.webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); setUp(() async { diff --git a/lib/web_ui/test/html/compositing/dom_mask_filter_golden_test.dart b/lib/web_ui/test/html/compositing/dom_mask_filter_golden_test.dart index 17ada251ff4eb..bf7e63d20fb0e 100644 --- a/lib/web_ui/test/html/compositing/dom_mask_filter_golden_test.dart +++ b/lib/web_ui/test/html/compositing/dom_mask_filter_golden_test.dart @@ -16,8 +16,8 @@ Future testMain() async { setUp(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); test('Should blur rectangles based on sigma.', () async { diff --git a/lib/web_ui/test/html/drawing/canvas_draw_color_golden_test.dart b/lib/web_ui/test/html/drawing/canvas_draw_color_golden_test.dart index 8201c2e808a6f..8b26b7342f6c1 100644 --- a/lib/web_ui/test/html/drawing/canvas_draw_color_golden_test.dart +++ b/lib/web_ui/test/html/drawing/canvas_draw_color_golden_test.dart @@ -18,8 +18,8 @@ Future testMain() async { debugShowClipLayers = true; SurfaceSceneBuilder.debugForgetFrameScene(); await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); tearDown(() { diff --git a/lib/web_ui/test/html/drawing/canvas_draw_picture_golden_test.dart b/lib/web_ui/test/html/drawing/canvas_draw_picture_golden_test.dart index c304c21c4033f..a2cfffb29e7b2 100644 --- a/lib/web_ui/test/html/drawing/canvas_draw_picture_golden_test.dart +++ b/lib/web_ui/test/html/drawing/canvas_draw_picture_golden_test.dart @@ -21,8 +21,8 @@ Future testMain() async { setUpAll(() async { debugShowClipLayers = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); setUp(() async { diff --git a/lib/web_ui/test/html/drawing/draw_vertices_golden_test.dart b/lib/web_ui/test/html/drawing/draw_vertices_golden_test.dart index cae9a0d2f5846..8a1a10ccb568d 100644 --- a/lib/web_ui/test/html/drawing/draw_vertices_golden_test.dart +++ b/lib/web_ui/test/html/drawing/draw_vertices_golden_test.dart @@ -25,8 +25,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); setUp(() { diff --git a/lib/web_ui/test/html/path_metrics_golden_test.dart b/lib/web_ui/test/html/path_metrics_golden_test.dart index 998e8ae7d2eea..070a2e4ebcfb6 100644 --- a/lib/web_ui/test/html/path_metrics_golden_test.dart +++ b/lib/web_ui/test/html/path_metrics_golden_test.dart @@ -25,8 +25,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); test('Should calculate tangent on line', () async { diff --git a/lib/web_ui/test/html/path_transform_golden_test.dart b/lib/web_ui/test/html/path_transform_golden_test.dart index 6792cc159c422..cb5b398169540 100644 --- a/lib/web_ui/test/html/path_transform_golden_test.dart +++ b/lib/web_ui/test/html/path_transform_golden_test.dart @@ -23,8 +23,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); test('Should draw transformed line.', () async { diff --git a/lib/web_ui/test/html/screenshot.dart b/lib/web_ui/test/html/screenshot.dart index cbeb620635767..3e2226ae68803 100644 --- a/lib/web_ui/test/html/screenshot.dart +++ b/lib/web_ui/test/html/screenshot.dart @@ -77,7 +77,7 @@ Future sceneScreenshot(SurfaceSceneBuilder sceneBuilder, String fileName, void setUpStableTestFonts() { setUpAll(() async { await ui.webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); } diff --git a/lib/web_ui/test/html/shaders/image_shader_golden_test.dart b/lib/web_ui/test/html/shaders/image_shader_golden_test.dart index 959f17c74241a..405250062d462 100644 --- a/lib/web_ui/test/html/shaders/image_shader_golden_test.dart +++ b/lib/web_ui/test/html/shaders/image_shader_golden_test.dart @@ -27,8 +27,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); void drawShapes(RecordingCanvas rc, SurfacePaint paint, Rect shaderRect) { diff --git a/lib/web_ui/test/html/shaders/linear_gradient_golden_test.dart b/lib/web_ui/test/html/shaders/linear_gradient_golden_test.dart index 8b0a8534ebfb1..742067e4914e0 100644 --- a/lib/web_ui/test/html/shaders/linear_gradient_golden_test.dart +++ b/lib/web_ui/test/html/shaders/linear_gradient_golden_test.dart @@ -21,8 +21,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); test('Should draw linear gradient using rectangle.', () async { diff --git a/lib/web_ui/test/html/shaders/radial_gradient_golden_test.dart b/lib/web_ui/test/html/shaders/radial_gradient_golden_test.dart index bedc35f59e391..51bfab70965a1 100644 --- a/lib/web_ui/test/html/shaders/radial_gradient_golden_test.dart +++ b/lib/web_ui/test/html/shaders/radial_gradient_golden_test.dart @@ -17,8 +17,8 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); Future testGradient(String fileName, Shader shader, diff --git a/lib/web_ui/test/html/shaders/shader_mask_golden_test.dart b/lib/web_ui/test/html/shaders/shader_mask_golden_test.dart index 20065ddef27ea..6c11494b9f8f0 100644 --- a/lib/web_ui/test/html/shaders/shader_mask_golden_test.dart +++ b/lib/web_ui/test/html/shaders/shader_mask_golden_test.dart @@ -41,8 +41,8 @@ Future testMain() async { scene.remove(); } initWebGl(); - renderer.fontCollection.debugRegisterTestFonts(); - await renderer.fontCollection.ensureFontsLoaded(); + await renderer.fontCollection.debugDownloadTestFonts(); + renderer.fontCollection.registerDownloadedFonts(); }); /// Should render the picture unmodified. diff --git a/lib/web_ui/test/text/font_collection_test.dart b/lib/web_ui/test/text/font_collection_test.dart index 3e2e0b183752d..663fc59536e86 100644 --- a/lib/web_ui/test/text/font_collection_test.dart +++ b/lib/web_ui/test/text/font_collection_test.dart @@ -29,9 +29,10 @@ void testMain() { const String testFontFamily = 'Ahem'; final List fontFamilyList = []; - fontManager.registerAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.ensureFontsLoaded(); + await fontManager.testFillDownloadedFonts(); + fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { fontFamilyList.add(f.family!); @@ -45,9 +46,10 @@ void testMain() { const String testFontFamily = 'Ahem ahem ahem'; final List fontFamilyList = []; - fontManager.registerAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.ensureFontsLoaded(); + await fontManager.testFillDownloadedFonts(); + fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { fontFamilyList.add(f.family!); @@ -63,9 +65,10 @@ void testMain() { const String testFontFamily = 'AhEm'; final List fontFamilyList = []; - fontManager.registerAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.ensureFontsLoaded(); + await fontManager.testFillDownloadedFonts(); + fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { fontFamilyList.add(f.family!); @@ -81,9 +84,10 @@ void testMain() { const String testFontFamily = '/Ahem'; final List fontFamilyList = []; - fontManager.registerAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.ensureFontsLoaded(); + await fontManager.testFillDownloadedFonts(); + fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { fontFamilyList.add(f.family!); @@ -105,9 +109,10 @@ void testMain() { const String testFontFamily = 'Ahem!!ahem'; final List fontFamilyList = []; - fontManager.registerAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.ensureFontsLoaded(); + await fontManager.testFillDownloadedFonts(); + fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { fontFamilyList.add(f.family!); @@ -129,9 +134,10 @@ void testMain() { const String testFontFamily = 'Ahem ,ahem'; final List fontFamilyList = []; - fontManager.registerAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.ensureFontsLoaded(); + await fontManager.testFillDownloadedFonts(); + fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { fontFamilyList.add(f.family!); @@ -154,9 +160,10 @@ void testMain() { const String testFontFamily = 'Ahem 1998'; final List fontFamilyList = []; - fontManager.registerAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.ensureFontsLoaded(); + await fontManager.testFillDownloadedFonts(); + fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { fontFamilyList.add(f.family!); From 2126463ec26db840c6be5b1801ce8c6a92feeb26 Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Fri, 21 Oct 2022 15:00:46 -0700 Subject: [PATCH 3/9] removed unused function --- lib/web_ui/lib/src/engine/text/font_collection.dart | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/web_ui/lib/src/engine/text/font_collection.dart b/lib/web_ui/lib/src/engine/text/font_collection.dart index 176fe24b80fca..d037cae47cab2 100644 --- a/lib/web_ui/lib/src/engine/text/font_collection.dart +++ b/lib/web_ui/lib/src/engine/text/font_collection.dart @@ -113,11 +113,6 @@ class HtmlFontCollection implements FontCollection { domDocument.fonts!.clear(); } } - - @override - Future addPendingFonts() async { - return; - } } /// Manages a collection of fonts and ensures they are loaded. From 03770764dc1ad53cd0e740fbc56d0ed96cbce37b Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Fri, 21 Oct 2022 16:51:02 -0700 Subject: [PATCH 4/9] cleaned code and fixed polyfill font manager --- .../lib/src/engine/canvaskit/fonts.dart | 6 ++--- lib/web_ui/lib/src/engine/fonts.dart | 8 +++++++ lib/web_ui/lib/src/engine/initialization.dart | 6 ++--- .../lib/src/engine/text/font_collection.dart | 24 +++++++++++++------ .../canvaskit/skia_font_collection_test.dart | 1 - .../test/html/path_metrics_golden_test.dart | 2 +- .../test/text/font_collection_test.dart | 14 +++++------ 7 files changed, 39 insertions(+), 22 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart index ef40719921678..7f2bf5c3c3723 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart @@ -163,9 +163,9 @@ class SkiaFontCollection implements FontCollection { unregisteredFont.url, unregisteredFont.family ); - if (registeredFont != null) { - _registeredFonts.add(registeredFont); - } + if (registeredFont != null) { + _registeredFonts.add(registeredFont); + } } _unregisteredFonts.clear(); diff --git a/lib/web_ui/lib/src/engine/fonts.dart b/lib/web_ui/lib/src/engine/fonts.dart index 39b607d18afc5..3f093359fee36 100644 --- a/lib/web_ui/lib/src/engine/fonts.dart +++ b/lib/web_ui/lib/src/engine/fonts.dart @@ -9,7 +9,15 @@ import 'assets.dart'; abstract class FontCollection { Future loadFontFromList(Uint8List list, {String? fontFamily}); + + /// Completes when fonts from FontManifest.json have been downloaded. Future downloadAssetFonts(AssetManager assetManager); + + /// Registeres fonts that have been downloaded but not yet registered with the + /// TypefaceFontProvider. + /// + /// downloading of fonts happens separately from registering of fonts so that + /// the download step can happen concurrently with the download of wasm. void registerDownloadedFonts(); FutureOr debugDownloadTestFonts(); void clear(); diff --git a/lib/web_ui/lib/src/engine/initialization.dart b/lib/web_ui/lib/src/engine/initialization.dart index 707c184327000..f7659254dce91 100644 --- a/lib/web_ui/lib/src/engine/initialization.dart +++ b/lib/web_ui/lib/src/engine/initialization.dart @@ -208,7 +208,7 @@ Future initializeEngineServices({ _setAssetManager(assetManager); Future initializeRendererCallback () async => renderer.initialize(); - await Future.wait(>[initializeRendererCallback(), _downloadAssetFonts(assetManager)]); + await Future.wait(>[initializeRendererCallback(), _downloadAssetFonts()]); renderer.fontCollection.registerDownloadedFonts(); _initializationState = DebugEngineInitializationState.initializedServices; } @@ -253,11 +253,11 @@ void _setAssetManager(AssetManager assetManager) { _assetManager = assetManager; } -Future _downloadAssetFonts(AssetManager assetManager) async { +Future _downloadAssetFonts() async { renderer.fontCollection.clear(); if (_assetManager != null) { - await renderer.fontCollection.downloadAssetFonts(assetManager); + await renderer.fontCollection.downloadAssetFonts(_assetManager!); } if (ui.debugEmulateFlutterTesterEnvironment) { diff --git a/lib/web_ui/lib/src/engine/text/font_collection.dart b/lib/web_ui/lib/src/engine/text/font_collection.dart index d037cae47cab2..3b019e129d089 100644 --- a/lib/web_ui/lib/src/engine/text/font_collection.dart +++ b/lib/web_ui/lib/src/engine/text/font_collection.dart @@ -216,15 +216,11 @@ class FontManager { if (_downloadedFonts.isEmpty) { return; } - - for (final DomFontFace? fontFace in _downloadedFonts) { - if (fontFace != null) { - domDocument.fonts!.add(fontFace); - } - } + _downloadedFonts.forEach(domDocument.fonts!.add); } - Future testFillDownloadedFonts() async { + + Future fillDownloadedFonts() async { final List loadedFonts = await Future.wait(_fontLoadingFutures); _downloadedFonts.addAll(loadedFonts.whereType()); } @@ -264,6 +260,13 @@ class _PolyfillFontManager extends FontManager { static const Duration _fontLoadTimeout = Duration(seconds: 2); static const Duration _fontLoadRetryDuration = Duration(milliseconds: 50); + final List> _completerFutures = >[]; + + @override + Future fillDownloadedFonts() async { + await Future.wait(_completerFutures); + } + @override void downloadAsset( String family, @@ -289,13 +292,18 @@ class _PolyfillFontManager extends FontManager { paragraph.style.fontFamily = "'$family', $fallbackFontName"; + final Completer completer = Completer(); + late DateTime fontLoadStart; void watchWidth() { if (paragraph.offsetWidth != sansSerifWidth) { paragraph.remove(); + completer.complete(); } else { if (DateTime.now().difference(fontLoadStart) > _fontLoadTimeout) { + // Let application waiting for fonts continue with fallback. + completer.complete(); // Throw unhandled exception for logging. throw Exception('Timed out trying to load font: $family'); } else { @@ -331,5 +339,7 @@ class _PolyfillFontManager extends FontManager { fontLoadStart = DateTime.now(); watchWidth(); + + _completerFutures.add(completer.future); } } diff --git a/lib/web_ui/test/canvaskit/skia_font_collection_test.dart b/lib/web_ui/test/canvaskit/skia_font_collection_test.dart index 97668652c7fdf..9dc43898158e5 100644 --- a/lib/web_ui/test/canvaskit/skia_font_collection_test.dart +++ b/lib/web_ui/test/canvaskit/skia_font_collection_test.dart @@ -137,7 +137,6 @@ void testMain() { /// Fonts should now be registered and _registeredFonts should be filled expect(fontCollection.debugRegisteredFonts, isNotEmpty); expect(warnings, isEmpty); - }); }); } diff --git a/lib/web_ui/test/html/path_metrics_golden_test.dart b/lib/web_ui/test/html/path_metrics_golden_test.dart index 070a2e4ebcfb6..49410f5f9c70b 100644 --- a/lib/web_ui/test/html/path_metrics_golden_test.dart +++ b/lib/web_ui/test/html/path_metrics_golden_test.dart @@ -25,7 +25,7 @@ Future testMain() async { setUpAll(() async { debugEmulateFlutterTesterEnvironment = true; await webOnlyInitializePlatform(); - renderer.fontCollection.debugDownloadTestFonts(); + await renderer.fontCollection.debugDownloadTestFonts(); renderer.fontCollection.registerDownloadedFonts(); }); diff --git a/lib/web_ui/test/text/font_collection_test.dart b/lib/web_ui/test/text/font_collection_test.dart index 663fc59536e86..27e33feb21d74 100644 --- a/lib/web_ui/test/text/font_collection_test.dart +++ b/lib/web_ui/test/text/font_collection_test.dart @@ -31,7 +31,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.testFillDownloadedFonts(); + await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -48,7 +48,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.testFillDownloadedFonts(); + await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -67,7 +67,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.testFillDownloadedFonts(); + await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -86,7 +86,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.testFillDownloadedFonts(); + await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -111,7 +111,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.testFillDownloadedFonts(); + await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -136,7 +136,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.testFillDownloadedFonts(); + await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -162,7 +162,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.testFillDownloadedFonts(); + await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { From b2b1a4eb775bda945fcd4d1e2ff9db8c788452d2 Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Sat, 22 Oct 2022 17:30:13 -0700 Subject: [PATCH 5/9] fixed error with futures --- .../lib/src/engine/text/font_collection.dart | 3 ++- lib/web_ui/test/text/font_collection_test.dart | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/web_ui/lib/src/engine/text/font_collection.dart b/lib/web_ui/lib/src/engine/text/font_collection.dart index 3b019e129d089..ba7c8bfbfe9ba 100644 --- a/lib/web_ui/lib/src/engine/text/font_collection.dart +++ b/lib/web_ui/lib/src/engine/text/font_collection.dart @@ -197,7 +197,8 @@ class FontManager { ) { Future fontFaceLoad(DomFontFace fontFace) async { try { - return fontFace.load(); + final DomFontFace loadedFontFace = await fontFace.load(); + return loadedFontFace; } catch (e) { printWarning('Error while trying to load font family "$family":\n$e'); return null; diff --git a/lib/web_ui/test/text/font_collection_test.dart b/lib/web_ui/test/text/font_collection_test.dart index 27e33feb21d74..e4383eb6422a4 100644 --- a/lib/web_ui/test/text/font_collection_test.dart +++ b/lib/web_ui/test/text/font_collection_test.dart @@ -29,7 +29,7 @@ void testMain() { const String testFontFamily = 'Ahem'; final List fontFamilyList = []; - fontManager.downloadAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); @@ -46,7 +46,7 @@ void testMain() { const String testFontFamily = 'Ahem ahem ahem'; final List fontFamilyList = []; - fontManager.downloadAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); @@ -65,7 +65,7 @@ void testMain() { const String testFontFamily = 'AhEm'; final List fontFamilyList = []; - fontManager.downloadAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); @@ -84,7 +84,7 @@ void testMain() { const String testFontFamily = '/Ahem'; final List fontFamilyList = []; - fontManager.downloadAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); @@ -109,7 +109,7 @@ void testMain() { const String testFontFamily = 'Ahem!!ahem'; final List fontFamilyList = []; - fontManager.downloadAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); @@ -134,7 +134,7 @@ void testMain() { const String testFontFamily = 'Ahem ,ahem'; final List fontFamilyList = []; - fontManager.downloadAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); @@ -160,7 +160,7 @@ void testMain() { const String testFontFamily = 'Ahem 1998'; final List fontFamilyList = []; - fontManager.downloadAsset( + fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); await fontManager.fillDownloadedFonts(); fontManager.registerDownloadedFonts(); From 04d8a50a7803b5da89eb9774f91964f06ec781ad Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Mon, 24 Oct 2022 10:19:07 -0700 Subject: [PATCH 6/9] removed incorrect empty list check in register fonts call --- lib/web_ui/lib/src/engine/canvaskit/fonts.dart | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart index 7f2bf5c3c3723..a18c705166d86 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart @@ -83,7 +83,7 @@ class SkiaFontCollection implements FontCollection { canvasKit.Typeface.MakeFreeTypeFaceFromData(list.buffer); if (typeface != null) { _registeredFonts.add(RegisteredFont(list, fontFamily, typeface)); - registerDownloadedFonts(); + _registerWithFontProvider(); } else { printWarning('Failed to parse font family "$fontFamily"'); return; @@ -135,7 +135,12 @@ class SkiaFontCollection implements FontCollection { } final List completedPendingFonts = await Future.wait(pendingFonts); - _unregisteredFonts.addAll(completedPendingFonts.whereType()); + for (final UnregisteredFont? unregFont in completedPendingFonts) { + if (unregFont != null) { + _unregisteredFonts.add(unregFont); + } + } + //_unregisteredFonts.addAll(completedPendingFonts.whereType()); } @override @@ -153,10 +158,6 @@ class SkiaFontCollection implements FontCollection { } } - if (_unregisteredFonts.isEmpty) { - return; - } - for (final UnregisteredFont unregisteredFont in _unregisteredFonts) { final RegisteredFont? registeredFont = makeRegisterFont( unregisteredFont.bytes, From 9939f7593319bba1b00591ee421fbc105365322f Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Mon, 24 Oct 2022 10:21:36 -0700 Subject: [PATCH 7/9] shorten code to add fonts to list --- lib/web_ui/lib/src/engine/canvaskit/fonts.dart | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart index a18c705166d86..694a015168e87 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/fonts.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/fonts.dart @@ -135,12 +135,7 @@ class SkiaFontCollection implements FontCollection { } final List completedPendingFonts = await Future.wait(pendingFonts); - for (final UnregisteredFont? unregFont in completedPendingFonts) { - if (unregFont != null) { - _unregisteredFonts.add(unregFont); - } - } - //_unregisteredFonts.addAll(completedPendingFonts.whereType()); + _unregisteredFonts.addAll(completedPendingFonts.whereType()); } @override From afb2f95cde6b0619a17a9036fd110ccb0d2004ad Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Mon, 24 Oct 2022 11:12:12 -0700 Subject: [PATCH 8/9] clarifying comments and cleaned up code --- lib/web_ui/lib/src/engine/fonts.dart | 18 ++++++++++++++---- .../lib/src/engine/text/font_collection.dart | 11 ++++------- lib/web_ui/test/text/font_collection_test.dart | 14 +++++++------- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/lib/web_ui/lib/src/engine/fonts.dart b/lib/web_ui/lib/src/engine/fonts.dart index 3f093359fee36..f124e88f94a47 100644 --- a/lib/web_ui/lib/src/engine/fonts.dart +++ b/lib/web_ui/lib/src/engine/fonts.dart @@ -8,16 +8,26 @@ import 'dart:typed_data'; import 'assets.dart'; abstract class FontCollection { + + /// Fonts loaded with [loadFontFromList] do not need to be registered + /// with [registerDownloadedFonts]. Fonts are both downloaded and registered + /// with [loadFontFromList] calls. Future loadFontFromList(Uint8List list, {String? fontFamily}); /// Completes when fonts from FontManifest.json have been downloaded. Future downloadAssetFonts(AssetManager assetManager); - /// Registeres fonts that have been downloaded but not yet registered with the - /// TypefaceFontProvider. + /// Registers both downloaded fonts and fallback fonts with the TypefaceFontProvider. + /// + /// Downloading of fonts happens separately from registering of fonts so that + /// the download step can happen concurrently with the initalization of the renderer. + /// + /// The correct order of calls to register downloaded fonts: + /// 1) [downloadAssetFonts] + /// 2) [registerDownloadedFonts] /// - /// downloading of fonts happens separately from registering of fonts so that - /// the download step can happen concurrently with the download of wasm. + /// For fallbackFonts, call registerFallbackFont (see font_fallbacks.dart) + /// for each fallback font before calling [registerDownloadedFonts] void registerDownloadedFonts(); FutureOr debugDownloadTestFonts(); void clear(); diff --git a/lib/web_ui/lib/src/engine/text/font_collection.dart b/lib/web_ui/lib/src/engine/text/font_collection.dart index ba7c8bfbfe9ba..29b4feaf15070 100644 --- a/lib/web_ui/lib/src/engine/text/font_collection.dart +++ b/lib/web_ui/lib/src/engine/text/font_collection.dart @@ -71,9 +71,7 @@ class HtmlFontCollection implements FontCollection { family!, 'url(${assetManager.getAssetUrl(asset)})', descriptors); } } - - final List loadedFonts = await Future.wait(_assetFontManager!._fontLoadingFutures); - _assetFontManager!._downloadedFonts.addAll(loadedFonts.whereType()); + await _assetFontManager!.downloadAllFonts(); } @override @@ -94,8 +92,7 @@ class HtmlFontCollection implements FontCollection { 'url($robotoTestFontUrl)', const {}); _testFontManager!.downloadAsset(robotoVariableFontFamily, 'url($robotoVariableTestFontUrl)', const {}); - final List loadedFonts = await Future.wait(_testFontManager!._fontLoadingFutures); - _testFontManager!._downloadedFonts.addAll(loadedFonts.whereType()); + await _testFontManager!.downloadAllFonts(); } @override @@ -221,7 +218,7 @@ class FontManager { } - Future fillDownloadedFonts() async { + Future downloadAllFonts() async { final List loadedFonts = await Future.wait(_fontLoadingFutures); _downloadedFonts.addAll(loadedFonts.whereType()); } @@ -264,7 +261,7 @@ class _PolyfillFontManager extends FontManager { final List> _completerFutures = >[]; @override - Future fillDownloadedFonts() async { + Future downloadAllFonts() async { await Future.wait(_completerFutures); } diff --git a/lib/web_ui/test/text/font_collection_test.dart b/lib/web_ui/test/text/font_collection_test.dart index e4383eb6422a4..8c074a2c38c70 100644 --- a/lib/web_ui/test/text/font_collection_test.dart +++ b/lib/web_ui/test/text/font_collection_test.dart @@ -31,7 +31,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.fillDownloadedFonts(); + await fontManager.downloadAllFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -48,7 +48,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.fillDownloadedFonts(); + await fontManager.downloadAllFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -67,7 +67,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.fillDownloadedFonts(); + await fontManager.downloadAllFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -86,7 +86,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.fillDownloadedFonts(); + await fontManager.downloadAllFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -111,7 +111,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.fillDownloadedFonts(); + await fontManager.downloadAllFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -136,7 +136,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.fillDownloadedFonts(); + await fontManager.downloadAllFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { @@ -162,7 +162,7 @@ void testMain() { fontManager.downloadAsset( testFontFamily, 'url($testFontUrl)', const {}); - await fontManager.fillDownloadedFonts(); + await fontManager.downloadAllFonts(); fontManager.registerDownloadedFonts(); domDocument.fonts! .forEach(allowInterop((DomFontFace f, DomFontFace f2, DomFontFaceSet s) { From 9d6540034e3178f7d8dbd9589bf53c6fced3f1b7 Mon Sep 17 00:00:00 2001 From: alanwutang11 Date: Mon, 24 Oct 2022 13:23:56 -0700 Subject: [PATCH 9/9] override registerDownloadedFonts in polyfll font manager --- lib/web_ui/lib/src/engine/text/font_collection.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/web_ui/lib/src/engine/text/font_collection.dart b/lib/web_ui/lib/src/engine/text/font_collection.dart index 29b4feaf15070..74b49b23d1559 100644 --- a/lib/web_ui/lib/src/engine/text/font_collection.dart +++ b/lib/web_ui/lib/src/engine/text/font_collection.dart @@ -265,6 +265,9 @@ class _PolyfillFontManager extends FontManager { await Future.wait(_completerFutures); } + @override + void registerDownloadedFonts() {} + @override void downloadAsset( String family,