Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/ui/dart_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions lib/ui/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> loadFontFromList(Uint8List list, {String fontFamily}) {
return _futurize(
(_Callback<void> callback) => _loadFontFromList(list, callback, fontFamily)
);
}

String _loadFontFromList(Uint8List list, _Callback<void> callback, String fontFamily) native 'loadFontFromList';
51 changes: 50 additions & 1 deletion lib/ui/text/font_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,62 @@
#include <mutex>

#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"
#include "third_party/skia/include/core/SkFontMgr.h"
#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 =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bump this to the IO thread?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept this on the UI thread for now - it just parses the font's metadata and doesn't take much time, and it's expected to be used during initialization. We can move it to the IO thread if it becomes a bottleneck.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm

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<txt::FontCollection>()) {
collection_->SetDefaultFontManager(SkFontMgr::RefDefault());

dynamic_font_manager_ = sk_make_sp<txt::DynamicFontManager>();
collection_->SetDynamicFontManager(dynamic_font_manager_);
}

FontCollection::~FontCollection() {
collection_.reset();
SkGraphics::PurgeFontCache();
}

void FontCollection::RegisterNatives(tonic::DartLibraryNatives* natives) {
natives->Register({
{"loadFontFromList", _LoadFontFromList, 3, true},
});
}

std::shared_ptr<txt::FontCollection> FontCollection::GetFontCollection() const {
return collection_;
}
Expand Down Expand Up @@ -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<SkStreamAsset> font_stream =
std::make_unique<SkMemoryStream>(font_data, length, true);
sk_sp<SkTypeface> 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
11 changes: 11 additions & 0 deletions lib/ui/text/font_collection.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -21,14 +25,21 @@ class FontCollection {

~FontCollection();

static void RegisterNatives(tonic::DartLibraryNatives* natives);

std::shared_ptr<txt::FontCollection> GetFontCollection() const;

void RegisterFonts(fml::RefPtr<AssetManager> asset_manager);

void RegisterTestFonts();

void LoadFontFromList(const uint8_t* font_data,
int length,
std::string family_name);

private:
std::shared_ptr<txt::FontCollection> collection_;
sk_sp<txt::DynamicFontManager> dynamic_font_manager_;

FML_DISALLOW_COPY_AND_ASSIGN(FontCollection);
};
Expand Down
13 changes: 12 additions & 1 deletion third_party/txt/src/txt/asset_font_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -35,9 +36,9 @@ class AssetFontManager : public SkFontMgr {
// |SkFontMgr|
SkFontStyleSet* onMatchFamily(const char familyName[]) const override;

private:
std::unique_ptr<FontAssetProvider> font_provider_;

private:
// |SkFontMgr|
int onCountFamilies() const override;

Expand Down Expand Up @@ -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>()) {}

TypefaceFontAssetProvider& font_provider() {
return static_cast<TypefaceFontAssetProvider&>(*font_provider_);
}
};

} // namespace txt

#endif // TXT_ASSET_FONT_MANAGER_H_
6 changes: 6 additions & 0 deletions third_party/txt/src/txt/font_collection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ void FontCollection::SetAssetFontManager(sk_sp<SkFontMgr> font_manager) {
asset_font_manager_ = font_manager;
}

void FontCollection::SetDynamicFontManager(sk_sp<SkFontMgr> font_manager) {
dynamic_font_manager_ = font_manager;
}

void FontCollection::SetTestFontManager(sk_sp<SkFontMgr> font_manager) {
test_font_manager_ = font_manager;
}
Expand All @@ -93,6 +97,8 @@ std::vector<sk_sp<SkFontMgr>> FontCollection::GetFontManagerOrder() const {
std::vector<sk_sp<SkFontMgr>> 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_)
Expand Down
2 changes: 2 additions & 0 deletions third_party/txt/src/txt/font_collection.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class FontCollection : public std::enable_shared_from_this<FontCollection> {

void SetDefaultFontManager(sk_sp<SkFontMgr> font_manager);
void SetAssetFontManager(sk_sp<SkFontMgr> font_manager);
void SetDynamicFontManager(sk_sp<SkFontMgr> font_manager);
void SetTestFontManager(sk_sp<SkFontMgr> font_manager);

std::shared_ptr<minikin::FontCollection> GetMinikinFontCollectionForFamily(
Expand Down Expand Up @@ -73,6 +74,7 @@ class FontCollection : public std::enable_shared_from_this<FontCollection> {

sk_sp<SkFontMgr> default_font_manager_;
sk_sp<SkFontMgr> asset_font_manager_;
sk_sp<SkFontMgr> dynamic_font_manager_;
sk_sp<SkFontMgr> test_font_manager_;
std::unordered_map<FamilyKey,
std::shared_ptr<minikin::FontCollection>,
Expand Down