Flutter Engine
font_collection.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/lib/ui/text/font_collection.h"
6 
7 #include <mutex>
8 
9 #include "flutter/lib/ui/text/asset_manager_font_provider.h"
10 #include "flutter/lib/ui/ui_dart_state.h"
11 #include "flutter/lib/ui/window/platform_configuration.h"
12 #include "flutter/runtime/test_font_data.h"
13 #include "rapidjson/document.h"
14 #include "rapidjson/rapidjson.h"
15 #include "third_party/skia/include/core/SkFontMgr.h"
16 #include "third_party/skia/include/core/SkGraphics.h"
17 #include "third_party/skia/include/core/SkStream.h"
18 #include "third_party/skia/include/core/SkTypeface.h"
23 #include "txt/asset_font_manager.h"
24 #include "txt/test_font_manager.h"
25 
26 namespace flutter {
27 
28 namespace {
29 
30 void LoadFontFromList(tonic::Uint8List& font_data, // NOLINT
31  Dart_Handle callback,
32  std::string family_name) {
33  FontCollection& font_collection = UIDartState::Current()
35  ->client()
37  font_collection.LoadFontFromList(font_data.data(), font_data.num_elements(),
38  family_name);
39  font_data.Release();
40  tonic::DartInvoke(callback, {tonic::ToDart(0)});
41 }
42 
43 void _LoadFontFromList(Dart_NativeArguments args) {
45  tonic::DartCallStatic(LoadFontFromList, args);
46 }
47 
48 } // namespace
49 
51  : collection_(std::make_shared<txt::FontCollection>()) {
52  dynamic_font_manager_ = sk_make_sp<txt::DynamicFontManager>();
53  collection_->SetDynamicFontManager(dynamic_font_manager_);
54 }
55 
57  collection_.reset();
58  SkGraphics::PurgeFontCache();
59 }
60 
62  natives->Register({
63  {"loadFontFromList", _LoadFontFromList, 3, true},
64  });
65 }
66 
67 std::shared_ptr<txt::FontCollection> FontCollection::GetFontCollection() const {
68  return collection_;
69 }
70 
72  uint32_t font_initialization_data) {
73  collection_->SetupDefaultFontManager(font_initialization_data);
74 }
75 
77  std::shared_ptr<AssetManager> asset_manager) {
78  std::unique_ptr<fml::Mapping> manifest_mapping =
79  asset_manager->GetAsMapping("FontManifest.json");
80  if (manifest_mapping == nullptr) {
81  FML_DLOG(WARNING) << "Could not find the font manifest in the asset store.";
82  return;
83  }
84 
85  rapidjson::Document document;
86  static_assert(sizeof(decltype(document)::Ch) == sizeof(uint8_t), "");
87  document.Parse(reinterpret_cast<const decltype(document)::Ch*>(
88  manifest_mapping->GetMapping()),
89  manifest_mapping->GetSize());
90 
91  if (document.HasParseError()) {
92  FML_DLOG(WARNING) << "Error parsing the font manifest in the asset store.";
93  return;
94  }
95 
96  // Structure described in https://flutter.io/custom-fonts/
97 
98  if (!document.IsArray()) {
99  return;
100  }
101 
102  auto font_provider =
103  std::make_unique<AssetManagerFontProvider>(asset_manager);
104 
105  for (const auto& family : document.GetArray()) {
106  auto family_name = family.FindMember("family");
107  if (family_name == family.MemberEnd() || !family_name->value.IsString()) {
108  continue;
109  }
110 
111  auto family_fonts = family.FindMember("fonts");
112  if (family_fonts == family.MemberEnd() || !family_fonts->value.IsArray()) {
113  continue;
114  }
115 
116  for (const auto& family_font : family_fonts->value.GetArray()) {
117  if (!family_font.IsObject()) {
118  continue;
119  }
120 
121  auto font_asset = family_font.FindMember("asset");
122  if (font_asset == family_font.MemberEnd() ||
123  !font_asset->value.IsString()) {
124  continue;
125  }
126 
127  // TODO(chinmaygarde): Handle weights and styles.
128  font_provider->RegisterAsset(family_name->value.GetString(),
129  font_asset->value.GetString());
130  }
131  }
132 
133  collection_->SetAssetFontManager(
134  sk_make_sp<txt::AssetFontManager>(std::move(font_provider)));
135 }
136 
138  std::vector<sk_sp<SkTypeface>> test_typefaces;
139  std::vector<std::unique_ptr<SkStreamAsset>> font_data = GetTestFontData();
140  for (auto& font : font_data) {
141  test_typefaces.push_back(SkTypeface::MakeFromStream(std::move(font)));
142  }
143 
144  std::unique_ptr<txt::TypefaceFontAssetProvider> font_provider =
145  std::make_unique<txt::TypefaceFontAssetProvider>();
146 
147  size_t index = 0;
148  std::vector<std::string> names = GetTestFontFamilyNames();
149  for (sk_sp<SkTypeface> typeface : test_typefaces) {
150  font_provider->RegisterTypeface(std::move(typeface), names[index]);
151  index++;
152  }
153 
154  collection_->SetTestFontManager(
155  sk_make_sp<txt::TestFontManager>(std::move(font_provider), names));
156 
157  collection_->DisableFontFallback();
158 }
159 
160 void FontCollection::LoadFontFromList(const uint8_t* font_data,
161  int length,
162  std::string family_name) {
163  std::unique_ptr<SkStreamAsset> font_stream =
164  std::make_unique<SkMemoryStream>(font_data, length, true);
165  sk_sp<SkTypeface> typeface =
166  SkTypeface::MakeFromStream(std::move(font_stream));
167  txt::TypefaceFontAssetProvider& font_provider =
168  dynamic_font_manager_->font_provider();
169  if (family_name.empty()) {
170  font_provider.RegisterTypeface(typeface);
171  } else {
172  font_provider.RegisterTypeface(typeface, family_name);
173  }
174  collection_->ClearFontFamilyCache();
175 }
176 
177 } // namespace flutter
PlatformConfigurationClient * client() const
Access to the platform configuration client (which typically is implemented by the RuntimeController)...
G_BEGIN_DECLS FlValue * args
virtual FontCollection & GetFontCollection()=0
Returns the current collection of fonts available on the platform.
static void RegisterNatives(tonic::DartLibraryNatives *natives)
void DartCallStatic(Sig func, Dart_NativeArguments args)
Definition: dart_args.h:208
std::vector< std::unique_ptr< SkStreamAsset > > GetTestFontData()
Definition: ref_ptr.h:252
std::vector< std::string > GetTestFontFamilyNames()
std::shared_ptr< txt::FontCollection > GetFontCollection() const
Dart_Handle DartInvoke(Dart_Handle closure, std::initializer_list< Dart_Handle > args)
Definition: dart_invoke.cc:20
void LoadFontFromList(const uint8_t *font_data, int length, std::string family_name)
void RegisterFonts(std::shared_ptr< AssetManager > asset_manager)
FlKeyEvent FlKeyResponderAsyncCallback callback
void Register(std::initializer_list< Entry > entries)
static void ThrowIfUIOperationsProhibited()
PlatformConfiguration * platform_configuration() const
size_t length
#define FML_DLOG(severity)
Definition: logging.h:85
Dart_Handle ToDart(const T &object)
void RegisterTypeface(sk_sp< SkTypeface > typeface)
void SetupDefaultFontManager(uint32_t font_initialization_data)
static UIDartState * Current()