diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index d5c923031a922..181f7345f8ef2 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -24,6 +24,7 @@ #include "flutter/lib/ui/painting/vertices.h" #include "flutter/lib/ui/semantics/semantics_update.h" #include "flutter/lib/ui/semantics/semantics_update_builder.h" +#include "flutter/lib/ui/text/font_collection.h" #include "flutter/lib/ui/text/paragraph.h" #include "flutter/lib/ui/text/paragraph_builder.h" #include "flutter/lib/ui/window/window.h" @@ -72,6 +73,7 @@ void DartUI::InitForGlobal() { Codec::RegisterNatives(g_natives); DartRuntimeHooks::RegisterNatives(g_natives); EngineLayer::RegisterNatives(g_natives); + FontCollection::RegisterNatives(g_natives); FrameInfo::RegisterNatives(g_natives); ImageFilter::RegisterNatives(g_natives); ImageShader::RegisterNatives(g_natives); diff --git a/lib/ui/text.dart b/lib/ui/text.dart index 99c7da939d0ab..664cbaedef276 100644 --- a/lib/ui/text.dart +++ b/lib/ui/text.dart @@ -1087,3 +1087,16 @@ class ParagraphBuilder extends NativeFieldWrapperClass2 { /// cannot be used further. Paragraph build() native 'ParagraphBuilder_build'; } + +/// Loads a font from a buffer and makes it available for rendering text. +/// +/// * `list`: A list of bytes containing the font file. +/// * `fontFamily`: The family name used to identify the font in text styles. +/// If this is not provided, then the family name will be extracted from the font file. +Future loadFontFromList(Uint8List list, {String fontFamily}) { + return _futurize( + (_Callback callback) => _loadFontFromList(list, callback, fontFamily) + ); +} + +String _loadFontFromList(Uint8List list, _Callback callback, String fontFamily) native 'loadFontFromList'; diff --git a/lib/ui/text/font_collection.cc b/lib/ui/text/font_collection.cc index 6025fb6a93520..83166f96bbf9d 100644 --- a/lib/ui/text/font_collection.cc +++ b/lib/ui/text/font_collection.cc @@ -7,6 +7,8 @@ #include #include "flutter/lib/ui/text/asset_manager_font_provider.h" +#include "flutter/lib/ui/ui_dart_state.h" +#include "flutter/lib/ui/window/window.h" #include "flutter/runtime/test_font_data.h" #include "rapidjson/document.h" #include "rapidjson/rapidjson.h" @@ -14,15 +16,40 @@ #include "third_party/skia/include/core/SkGraphics.h" #include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkTypeface.h" +#include "third_party/tonic/dart_args.h" +#include "third_party/tonic/dart_library_natives.h" +#include "third_party/tonic/logging/dart_invoke.h" +#include "third_party/tonic/typed_data/uint8_list.h" #include "txt/asset_font_manager.h" #include "txt/test_font_manager.h" -#include "txt/typeface_font_asset_provider.h" namespace blink { +namespace { + +void LoadFontFromList(tonic::Uint8List& font_data, + Dart_Handle callback, + std::string family_name) { + FontCollection& font_collection = + UIDartState::Current()->window()->client()->GetFontCollection(); + font_collection.LoadFontFromList(font_data.data(), font_data.num_elements(), + family_name); + font_data.Release(); + tonic::DartInvoke(callback, {tonic::ToDart(0)}); +} + +void _LoadFontFromList(Dart_NativeArguments args) { + tonic::DartCallStatic(LoadFontFromList, args); +} + +} // namespace + FontCollection::FontCollection() : collection_(std::make_shared()) { collection_->SetDefaultFontManager(SkFontMgr::RefDefault()); + + dynamic_font_manager_ = sk_make_sp(); + collection_->SetDynamicFontManager(dynamic_font_manager_); } FontCollection::~FontCollection() { @@ -30,6 +57,12 @@ FontCollection::~FontCollection() { SkGraphics::PurgeFontCache(); } +void FontCollection::RegisterNatives(tonic::DartLibraryNatives* natives) { + natives->Register({ + {"loadFontFromList", _LoadFontFromList, 3, true}, + }); +} + std::shared_ptr FontCollection::GetFontCollection() const { return collection_; } @@ -110,4 +143,20 @@ void FontCollection::RegisterTestFonts() { collection_->DisableFontFallback(); } +void FontCollection::LoadFontFromList(const uint8_t* font_data, + int length, + std::string family_name) { + std::unique_ptr font_stream = + std::make_unique(font_data, length, true); + sk_sp typeface = + SkTypeface::MakeFromStream(std::move(font_stream)); + txt::TypefaceFontAssetProvider& font_provider = + dynamic_font_manager_->font_provider(); + if (family_name.empty()) { + font_provider.RegisterTypeface(typeface); + } else { + font_provider.RegisterTypeface(typeface, family_name); + } +} + } // namespace blink diff --git a/lib/ui/text/font_collection.h b/lib/ui/text/font_collection.h index c9ef29cc05ade..a9bf31d73a2bc 100644 --- a/lib/ui/text/font_collection.h +++ b/lib/ui/text/font_collection.h @@ -13,6 +13,10 @@ #include "flutter/fml/memory/ref_ptr.h" #include "txt/font_collection.h" +namespace tonic { +class DartLibraryNatives; +} // namespace tonic + namespace blink { class FontCollection { @@ -21,14 +25,21 @@ class FontCollection { ~FontCollection(); + static void RegisterNatives(tonic::DartLibraryNatives* natives); + std::shared_ptr GetFontCollection() const; void RegisterFonts(fml::RefPtr asset_manager); void RegisterTestFonts(); + void LoadFontFromList(const uint8_t* font_data, + int length, + std::string family_name); + private: std::shared_ptr collection_; + sk_sp dynamic_font_manager_; FML_DISALLOW_COPY_AND_ASSIGN(FontCollection); }; diff --git a/third_party/txt/src/txt/asset_font_manager.h b/third_party/txt/src/txt/asset_font_manager.h index 9beb7b25ed866..715d81835edea 100644 --- a/third_party/txt/src/txt/asset_font_manager.h +++ b/third_party/txt/src/txt/asset_font_manager.h @@ -22,6 +22,7 @@ #include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/core/SkStream.h" #include "txt/font_asset_provider.h" +#include "txt/typeface_font_asset_provider.h" namespace txt { @@ -35,9 +36,9 @@ class AssetFontManager : public SkFontMgr { // |SkFontMgr| SkFontStyleSet* onMatchFamily(const char familyName[]) const override; - private: std::unique_ptr font_provider_; + private: // |SkFontMgr| int onCountFamilies() const override; @@ -84,6 +85,16 @@ class AssetFontManager : public SkFontMgr { FML_DISALLOW_COPY_AND_ASSIGN(AssetFontManager); }; +class DynamicFontManager : public AssetFontManager { + public: + DynamicFontManager() + : AssetFontManager(std::make_unique()) {} + + TypefaceFontAssetProvider& font_provider() { + return static_cast(*font_provider_); + } +}; + } // namespace txt #endif // TXT_ASSET_FONT_MANAGER_H_ diff --git a/third_party/txt/src/txt/font_collection.cc b/third_party/txt/src/txt/font_collection.cc index a54de304aa564..03e960a8d6dda 100644 --- a/third_party/txt/src/txt/font_collection.cc +++ b/third_party/txt/src/txt/font_collection.cc @@ -84,6 +84,10 @@ void FontCollection::SetAssetFontManager(sk_sp font_manager) { asset_font_manager_ = font_manager; } +void FontCollection::SetDynamicFontManager(sk_sp font_manager) { + dynamic_font_manager_ = font_manager; +} + void FontCollection::SetTestFontManager(sk_sp font_manager) { test_font_manager_ = font_manager; } @@ -93,6 +97,8 @@ std::vector> FontCollection::GetFontManagerOrder() const { std::vector> order; if (test_font_manager_) order.push_back(test_font_manager_); + if (dynamic_font_manager_) + order.push_back(dynamic_font_manager_); if (asset_font_manager_) order.push_back(asset_font_manager_); if (default_font_manager_) diff --git a/third_party/txt/src/txt/font_collection.h b/third_party/txt/src/txt/font_collection.h index ae723eb20dcbc..d512a6dd3ae26 100644 --- a/third_party/txt/src/txt/font_collection.h +++ b/third_party/txt/src/txt/font_collection.h @@ -42,6 +42,7 @@ class FontCollection : public std::enable_shared_from_this { void SetDefaultFontManager(sk_sp font_manager); void SetAssetFontManager(sk_sp font_manager); + void SetDynamicFontManager(sk_sp font_manager); void SetTestFontManager(sk_sp font_manager); std::shared_ptr GetMinikinFontCollectionForFamily( @@ -73,6 +74,7 @@ class FontCollection : public std::enable_shared_from_this { sk_sp default_font_manager_; sk_sp asset_font_manager_; + sk_sp dynamic_font_manager_; sk_sp test_font_manager_; std::unordered_map,