Skip to content

Commit

Permalink
An API for loading fonts from a buffer provided by the application (f…
Browse files Browse the repository at this point in the history
  • Loading branch information
jason-simmons authored Oct 12, 2018
1 parent 05aac0f commit f2e7441
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 2 deletions.
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 =
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

0 comments on commit f2e7441

Please sign in to comment.