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  collection_->SetupDefaultFontManager();
73 }
74 
76  std::shared_ptr<AssetManager> asset_manager) {
77  std::unique_ptr<fml::Mapping> manifest_mapping =
78  asset_manager->GetAsMapping("FontManifest.json");
79  if (manifest_mapping == nullptr) {
80  FML_DLOG(WARNING) << "Could not find the font manifest in the asset store.";
81  return;
82  }
83 
84  rapidjson::Document document;
85  static_assert(sizeof(decltype(document)::Ch) == sizeof(uint8_t), "");
86  document.Parse(reinterpret_cast<const decltype(document)::Ch*>(
87  manifest_mapping->GetMapping()),
88  manifest_mapping->GetSize());
89 
90  if (document.HasParseError()) {
91  FML_DLOG(WARNING) << "Error parsing the font manifest in the asset store.";
92  return;
93  }
94 
95  // Structure described in https://flutter.io/custom-fonts/
96 
97  if (!document.IsArray()) {
98  return;
99  }
100 
101  auto font_provider =
102  std::make_unique<AssetManagerFontProvider>(asset_manager);
103 
104  for (const auto& family : document.GetArray()) {
105  auto family_name = family.FindMember("family");
106  if (family_name == family.MemberEnd() || !family_name->value.IsString()) {
107  continue;
108  }
109 
110  auto family_fonts = family.FindMember("fonts");
111  if (family_fonts == family.MemberEnd() || !family_fonts->value.IsArray()) {
112  continue;
113  }
114 
115  for (const auto& family_font : family_fonts->value.GetArray()) {
116  if (!family_font.IsObject()) {
117  continue;
118  }
119 
120  auto font_asset = family_font.FindMember("asset");
121  if (font_asset == family_font.MemberEnd() ||
122  !font_asset->value.IsString()) {
123  continue;
124  }
125 
126  // TODO(chinmaygarde): Handle weights and styles.
127  font_provider->RegisterAsset(family_name->value.GetString(),
128  font_asset->value.GetString());
129  }
130  }
131 
132  collection_->SetAssetFontManager(
133  sk_make_sp<txt::AssetFontManager>(std::move(font_provider)));
134 }
135 
137  std::vector<sk_sp<SkTypeface>> test_typefaces;
138  std::vector<std::unique_ptr<SkStreamAsset>> font_data = GetTestFontData();
139  for (auto& font : font_data) {
140  test_typefaces.push_back(SkTypeface::MakeFromStream(std::move(font)));
141  }
142 
143  std::unique_ptr<txt::TypefaceFontAssetProvider> font_provider =
144  std::make_unique<txt::TypefaceFontAssetProvider>();
145 
146  size_t index = 0;
147  std::vector<std::string> names = GetTestFontFamilyNames();
148  for (sk_sp<SkTypeface> typeface : test_typefaces) {
149  font_provider->RegisterTypeface(std::move(typeface), names[index]);
150  index++;
151  }
152 
153  collection_->SetTestFontManager(
154  sk_make_sp<txt::TestFontManager>(std::move(font_provider), names));
155 
156  collection_->DisableFontFallback();
157 }
158 
159 void FontCollection::LoadFontFromList(const uint8_t* font_data,
160  int length,
161  std::string family_name) {
162  std::unique_ptr<SkStreamAsset> font_stream =
163  std::make_unique<SkMemoryStream>(font_data, length, true);
164  sk_sp<SkTypeface> typeface =
165  SkTypeface::MakeFromStream(std::move(font_stream));
166  txt::TypefaceFontAssetProvider& font_provider =
167  dynamic_font_manager_->font_provider();
168  if (family_name.empty()) {
169  font_provider.RegisterTypeface(typeface);
170  } else {
171  font_provider.RegisterTypeface(typeface, family_name);
172  }
173  collection_->ClearFontFamilyCache();
174 }
175 
176 } // namespace flutter
PlatformConfigurationClient * client() const
Access to the platform configuration client (which typically is implemented by the RuntimeController)...
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)
size_t length
void Register(std::initializer_list< Entry > entries)
static void ThrowIfUIOperationsProhibited()
PlatformConfiguration * platform_configuration() const
Definition: ui_dart_state.h:48
#define FML_DLOG(severity)
Definition: logging.h:85
Dart_Handle ToDart(const T &object)
void RegisterTypeface(sk_sp< SkTypeface > typeface)
static UIDartState * Current()