• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/asset_manager_font_provider.h"
6 
7 #include "flutter/fml/logging.h"
8 #include "third_party/skia/include/core/SkData.h"
9 #include "third_party/skia/include/core/SkStream.h"
10 #include "third_party/skia/include/core/SkString.h"
11 #include "third_party/skia/include/core/SkTypeface.h"
12 
13 namespace flutter {
14 
15 namespace {
16 
MappingReleaseProc(const void * ptr,void * context)17 void MappingReleaseProc(const void* ptr, void* context) {
18   delete reinterpret_cast<fml::Mapping*>(context);
19 }
20 
21 }  // anonymous namespace
22 
AssetManagerFontProvider(std::shared_ptr<AssetManager> asset_manager)23 AssetManagerFontProvider::AssetManagerFontProvider(
24     std::shared_ptr<AssetManager> asset_manager)
25     : asset_manager_(asset_manager) {}
26 
27 AssetManagerFontProvider::~AssetManagerFontProvider() = default;
28 
29 // |FontAssetProvider|
GetFamilyCount() const30 size_t AssetManagerFontProvider::GetFamilyCount() const {
31   return family_names_.size();
32 }
33 
34 // |FontAssetProvider|
GetFamilyName(int index) const35 std::string AssetManagerFontProvider::GetFamilyName(int index) const {
36   FML_DCHECK(index >= 0 && static_cast<size_t>(index) < family_names_.size());
37   return family_names_[index];
38 }
39 
40 // |FontAssetProvider|
MatchFamily(const std::string & family_name)41 SkFontStyleSet* AssetManagerFontProvider::MatchFamily(
42     const std::string& family_name) {
43   auto found = registered_families_.find(CanonicalFamilyName(family_name));
44   if (found == registered_families_.end()) {
45     return nullptr;
46   }
47   sk_sp<SkFontStyleSet> font_style_set = found->second;
48   return font_style_set.release();
49 }
50 
RegisterAsset(std::string family_name,std::string asset)51 void AssetManagerFontProvider::RegisterAsset(std::string family_name,
52                                              std::string asset) {
53   std::string canonical_name = CanonicalFamilyName(family_name);
54   auto family_it = registered_families_.find(canonical_name);
55 
56   if (family_it == registered_families_.end()) {
57     family_names_.push_back(family_name);
58     auto value = std::make_pair(
59         canonical_name, sk_make_sp<AssetManagerFontStyleSet>(asset_manager_));
60     family_it = registered_families_.emplace(value).first;
61   }
62 
63   family_it->second->registerAsset(asset);
64 }
65 
AssetManagerFontStyleSet(std::shared_ptr<AssetManager> asset_manager)66 AssetManagerFontStyleSet::AssetManagerFontStyleSet(
67     std::shared_ptr<AssetManager> asset_manager)
68     : asset_manager_(asset_manager) {}
69 
70 AssetManagerFontStyleSet::~AssetManagerFontStyleSet() = default;
71 
registerAsset(std::string asset)72 void AssetManagerFontStyleSet::registerAsset(std::string asset) {
73   assets_.emplace_back(asset);
74 }
75 
count()76 int AssetManagerFontStyleSet::count() {
77   return assets_.size();
78 }
79 
getStyle(int index,SkFontStyle *,SkString * style)80 void AssetManagerFontStyleSet::getStyle(int index,
81                                         SkFontStyle*,
82                                         SkString* style) {
83   FML_DCHECK(false);
84 }
85 
createTypeface(int i)86 SkTypeface* AssetManagerFontStyleSet::createTypeface(int i) {
87   size_t index = i;
88   if (index >= assets_.size())
89     return nullptr;
90 
91   TypefaceAsset& asset = assets_[index];
92   if (!asset.typeface) {
93     std::unique_ptr<fml::Mapping> asset_mapping =
94         asset_manager_->GetAsMapping(asset.asset);
95     if (asset_mapping == nullptr) {
96       return nullptr;
97     }
98 
99     fml::Mapping* asset_mapping_ptr = asset_mapping.release();
100     sk_sp<SkData> asset_data = SkData::MakeWithProc(
101         asset_mapping_ptr->GetMapping(), asset_mapping_ptr->GetSize(),
102         MappingReleaseProc, asset_mapping_ptr);
103     std::unique_ptr<SkMemoryStream> stream = SkMemoryStream::Make(asset_data);
104 
105     // Ownership of the stream is transferred.
106     asset.typeface = SkTypeface::MakeFromStream(std::move(stream));
107     if (!asset.typeface)
108       return nullptr;
109   }
110 
111   return SkRef(asset.typeface.get());
112 }
113 
matchStyle(const SkFontStyle & pattern)114 SkTypeface* AssetManagerFontStyleSet::matchStyle(const SkFontStyle& pattern) {
115   if (assets_.empty())
116     return nullptr;
117 
118   for (const TypefaceAsset& asset : assets_)
119     if (asset.typeface && asset.typeface->fontStyle() == pattern)
120       return SkRef(asset.typeface.get());
121 
122   return SkRef(assets_[0].typeface.get());
123 }
124 
TypefaceAsset(std::string a)125 AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(std::string a)
126     : asset(std::move(a)) {}
127 
128 AssetManagerFontStyleSet::TypefaceAsset::TypefaceAsset(
129     const AssetManagerFontStyleSet::TypefaceAsset& other) = default;
130 
131 AssetManagerFontStyleSet::TypefaceAsset::~TypefaceAsset() = default;
132 
133 }  // namespace flutter
134