diff --git a/lib/web_ui/lib/src/engine/browser_detection.dart b/lib/web_ui/lib/src/engine/browser_detection.dart index 4073b82b0c0f2..66801b61bc7ce 100644 --- a/lib/web_ui/lib/src/engine/browser_detection.dart +++ b/lib/web_ui/lib/src/engine/browser_detection.dart @@ -268,4 +268,6 @@ int _detectWebGLVersion() { } /// Whether the current browser supports the Chromium variant of CanvasKit. -final bool browserSupportsCanvaskitChromium = domIntl.v8BreakIterator != null; +const bool browserSupportsCanvaskitChromium = false; +// TODO(mdebbar): Uncomment this to enable real detection of browser support. +// final bool browserSupportsCanvaskitChromium = domIntl.v8BreakIterator != null; diff --git a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart index dbd01511304d6..d588da5a54c39 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart @@ -28,9 +28,21 @@ import 'renderer.dart'; /// Entrypoint into the CanvasKit API. late CanvasKit canvasKit; -// TODO(mdebbar): Turn this on when CanvasKit Chromium is ready. -// https://github.com/flutter/flutter/issues/122329 -const bool _enableCanvasKitChromiumInAutoMode = false; +late CanvasKitVariant _canvasKitVariant; + +/// Which variant of CanvasKit we are using. +CanvasKitVariant get canvasKitVariant => _canvasKitVariant; +set canvasKitVariant(CanvasKitVariant value) { + if (value == CanvasKitVariant.auto) { + throw ArgumentError.value( + value, + 'value', + 'CanvasKitVariant.auto is not a valid value for canvasKitVariant', + ); + } + _canvasKitVariant = value; +} + /// Sets the [CanvasKit] object on `window` so we can use `@JS()` to bind to /// static APIs. @@ -1872,13 +1884,6 @@ extension SkParagraphBuilderNamespaceExtension on SkParagraphBuilderNamespace { SkParagraphStyle paragraphStyle, TypefaceFontProvider? fontManager, ); - - bool RequiresClientICU() { - if (!js_util.hasProperty(this, 'RequiresClientICU')) { - return false; - } - return js_util.callMethod(this, 'RequiresClientICU', const [],) as bool; - } } @JS() @@ -2694,26 +2699,47 @@ void patchCanvasKitModule(DomHTMLScriptElement canvasKitScript) { } } +String get _canvasKitBaseUrl => configuration.canvasKitBaseUrl; + const String _kFullCanvasKitJsFileName = 'canvaskit.js'; const String _kChromiumCanvasKitJsFileName = 'chromium/canvaskit.js'; -String get _canvasKitBaseUrl => configuration.canvasKitBaseUrl; -List get _canvasKitJsFileNames { +// TODO(mdebbar): Replace this with a Record once it's supported in Dart. +class _CanvasKitVariantUrl { + const _CanvasKitVariantUrl(this.url, this.variant) + : assert( + variant != CanvasKitVariant.auto, + 'CanvasKitVariant.auto cannot have a url', + ); + + final String url; + final CanvasKitVariant variant; + + static _CanvasKitVariantUrl chromium = _CanvasKitVariantUrl( + '$_canvasKitBaseUrl$_kChromiumCanvasKitJsFileName', + CanvasKitVariant.chromium, + ); + + static _CanvasKitVariantUrl full = _CanvasKitVariantUrl( + '$_canvasKitBaseUrl$_kFullCanvasKitJsFileName', + CanvasKitVariant.full, + ); +} + +List<_CanvasKitVariantUrl> get _canvasKitUrls { switch (configuration.canvasKitVariant) { case CanvasKitVariant.auto: - return [ - if (_enableCanvasKitChromiumInAutoMode) _kChromiumCanvasKitJsFileName, - _kFullCanvasKitJsFileName, + return <_CanvasKitVariantUrl>[ + if (browserSupportsCanvaskitChromium) _CanvasKitVariantUrl.chromium, + _CanvasKitVariantUrl.full, ]; case CanvasKitVariant.full: - return [_kFullCanvasKitJsFileName]; + return <_CanvasKitVariantUrl>[_CanvasKitVariantUrl.full]; case CanvasKitVariant.chromium: - return [_kChromiumCanvasKitJsFileName]; + return <_CanvasKitVariantUrl>[_CanvasKitVariantUrl.chromium]; } } -Iterable get _canvasKitJsUrls { - return _canvasKitJsFileNames.map((String filename) => '$_canvasKitBaseUrl$filename'); -} + @visibleForTesting String canvasKitWasmModuleUrl(String file, String canvasKitBase) => canvasKitBase + file; @@ -2723,29 +2749,23 @@ String canvasKitWasmModuleUrl(String file, String canvasKitBase) => /// Downloads the CanvasKit JavaScript, then calls `CanvasKitInit` to download /// and intialize the CanvasKit wasm. Future downloadCanvasKit() async { - await _downloadOneOf(_canvasKitJsUrls); + await _downloadOneOf(_canvasKitUrls); - final CanvasKit canvasKit = await CanvasKitInit(CanvasKitInitOptions( + return CanvasKitInit(CanvasKitInitOptions( locateFile: allowInterop(canvasKitWasmModuleUrl), )); - - if (canvasKit.ParagraphBuilder.RequiresClientICU() && !browserSupportsCanvaskitChromium) { - throw Exception( - 'The CanvasKit variant you are using only works on Chromium browsers. ' - 'Please use a different CanvasKit variant, or use a Chromium browser.', - ); - } - - return canvasKit; } -/// Finds the first URL in [urls] that can be downloaded successfully, and +/// Finds the first entry in [urls] that can be downloaded successfully, and /// downloads it. /// /// If none of the URLs can be downloaded, throws an [Exception]. -Future _downloadOneOf(Iterable urls) async { - for (final String url in urls) { - if (await _downloadCanvasKitJs(url)) { +/// +/// Also sets [canvasKitVariant] to the variant of CanvasKit that was downloaded. +Future _downloadOneOf(Iterable<_CanvasKitVariantUrl> urls) async { + for (final _CanvasKitVariantUrl entry in urls) { + if (await _downloadCanvasKitJs(entry.url)) { + canvasKitVariant = entry.variant; return; } } diff --git a/lib/web_ui/lib/src/engine/canvaskit/text.dart b/lib/web_ui/lib/src/engine/canvaskit/text.dart index e885bd7da4fd5..dfd272ca3bf4d 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/text.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/text.dart @@ -984,7 +984,7 @@ class CkParagraphBuilder implements ui.ParagraphBuilder { /// Builds the CkParagraph with the builder and deletes the builder. SkParagraph _buildSkParagraph() { - if (canvasKit.ParagraphBuilder.RequiresClientICU()) { + if (canvasKitVariant == CanvasKitVariant.chromium) { injectClientICU(_paragraphBuilder); } final SkParagraph result = _paragraphBuilder.build(); diff --git a/lib/web_ui/lib/src/engine/canvaskit/text_fragmenter.dart b/lib/web_ui/lib/src/engine/canvaskit/text_fragmenter.dart index cf06f870ee0bf..dabee617230b0 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/text_fragmenter.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/text_fragmenter.dart @@ -7,6 +7,7 @@ import 'dart:typed_data'; import '../dom.dart'; import '../text/line_breaker.dart'; import 'canvaskit_api.dart'; +import 'renderer.dart'; /// Injects required ICU data into the [builder]. /// @@ -14,7 +15,7 @@ import 'canvaskit_api.dart'; /// without ICU data. void injectClientICU(SkParagraphBuilder builder) { assert( - canvasKit.ParagraphBuilder.RequiresClientICU(), + canvasKitVariant == CanvasKitVariant.chromium, 'This method should only be used with the CanvasKit Chromium variant.', ); diff --git a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart index 39ef01da27299..82602bd87c075 100644 --- a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart +++ b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart @@ -1624,7 +1624,7 @@ void _paragraphTests() { builder.pushStyle( canvasKit.TextStyle(SkTextStyleProperties()..halfLeading = true)); builder.pop(); - if (canvasKit.ParagraphBuilder.RequiresClientICU()) { + if (canvasKitVariant == CanvasKitVariant.chromium) { injectClientICU(builder); } final SkParagraph paragraph = builder.build(); @@ -1742,7 +1742,7 @@ void _paragraphTests() { ); builder.addText('hello'); - if (canvasKit.ParagraphBuilder.RequiresClientICU()) { + if (canvasKitVariant == CanvasKitVariant.chromium) { injectClientICU(builder); }