1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "font_collection.h"
17
18 #include "convert.h"
19 #include "text/typeface.h"
20 #include "utils/text_log.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 #define OHOS_THEME_FONT "OhosThemeFont"
25
Create()26 std::shared_ptr<FontCollection> FontCollection::Create()
27 {
28 static std::shared_ptr<FontCollection> instance = std::make_shared<AdapterTxt::FontCollection>();
29 return instance;
30 }
31
From(std::shared_ptr<txt::FontCollection> fontCollection)32 std::shared_ptr<FontCollection> FontCollection::From(std::shared_ptr<txt::FontCollection> fontCollection)
33 {
34 return std::make_shared<AdapterTxt::FontCollection>(fontCollection);
35 }
36
37 namespace AdapterTxt {
FontCollection(std::shared_ptr<txt::FontCollection> fontCollection)38 FontCollection::FontCollection(std::shared_ptr<txt::FontCollection> fontCollection)
39 : fontCollection_(fontCollection), dfmanager_(Drawing::FontMgr::CreateDynamicFontMgr())
40 {
41 if (fontCollection_ == nullptr) {
42 fontCollection_ = std::make_shared<txt::FontCollection>();
43 }
44 fontCollection_->SetupDefaultFontManager();
45 fontCollection_->SetDynamicFontManager(dfmanager_);
46 }
47
Get()48 std::shared_ptr<txt::FontCollection> FontCollection::Get()
49 {
50 return fontCollection_;
51 }
52
~FontCollection()53 FontCollection::~FontCollection()
54 {
55 if (Drawing::Typeface::GetTypefaceUnRegisterCallBack() == nullptr) {
56 return;
57 }
58
59 std::unique_lock<std::mutex> lock(mutex_);
60 for (const auto& [id, typeface] : typefaces_) {
61 Drawing::Typeface::GetTypefaceUnRegisterCallBack()(typeface);
62 }
63 typefaces_.clear();
64 }
65
DisableFallback()66 void FontCollection::DisableFallback()
67 {
68 fontCollection_->DisableFontFallback();
69 }
70
DisableSystemFont()71 void FontCollection::DisableSystemFont()
72 {
73 fontCollection_->SetDefaultFontManager(nullptr);
74 }
75
GetFontMgr()76 std::shared_ptr<Drawing::FontMgr> FontCollection::GetFontMgr()
77 {
78 return dfmanager_;
79 }
80
RegisterTypeface(std::shared_ptr<Drawing::Typeface> typeface)81 bool FontCollection::RegisterTypeface(std::shared_ptr<Drawing::Typeface> typeface)
82 {
83 if (!typeface || !Drawing::Typeface::GetTypefaceRegisterCallBack()) {
84 return false;
85 }
86
87 std::unique_lock<std::mutex> lock(mutex_);
88 if (typefaces_.find(typeface->GetUniqueID()) != typefaces_.end()) {
89 return true;
90 }
91 if (!Drawing::Typeface::GetTypefaceRegisterCallBack()(typeface)) {
92 return false;
93 }
94
95 typefaces_.emplace(typeface->GetUniqueID(), typeface);
96 return true;
97 }
98
LoadFont(const std::string & familyName,const uint8_t * data,size_t datalen)99 std::shared_ptr<Drawing::Typeface> FontCollection::LoadFont(
100 const std::string &familyName, const uint8_t *data, size_t datalen)
101 {
102 std::shared_ptr<Drawing::Typeface> typeface(dfmanager_->LoadDynamicFont(familyName, data, datalen));
103 if (!RegisterTypeface(typeface)) {
104 TEXT_LOGE("Failed to register typeface %{public}s", familyName.c_str());
105 return nullptr;
106 }
107 fontCollection_->ClearFontFamilyCache();
108 return typeface;
109 }
110
CreateTypeFace(const uint8_t * data,size_t datalen)111 static std::shared_ptr<Drawing::Typeface> CreateTypeFace(const uint8_t *data, size_t datalen)
112 {
113 if (datalen != 0 && data != nullptr) {
114 auto stream = std::make_unique<Drawing::MemoryStream>(data, datalen, true);
115 return Drawing::Typeface::MakeFromStream(std::move(stream));
116 }
117 return nullptr;
118 }
119
LoadThemeFont(const std::string & familyName,const uint8_t * data,size_t datalen)120 std::shared_ptr<Drawing::Typeface> FontCollection::LoadThemeFont(
121 const std::string &familyName, const uint8_t *data, size_t datalen)
122 {
123 std::shared_ptr<Drawing::Typeface> face = CreateTypeFace(data, datalen);
124 if (face != nullptr) {
125 std::string name = face->GetFamilyName();
126 uint32_t faceHash = face->GetHash();
127 for (auto item : typefaces_) {
128 if (faceHash == item.second->GetHash()) {
129 TEXT_LOGI("Find same theme font:family name:%{public}s, uniqueid:%{public}u, hash:%{public}u",
130 name.c_str(), item.second->GetUniqueID(), faceHash);
131 dfmanager_->LoadThemeFont(OHOS_THEME_FONT, item.second);
132 fontCollection_->ClearFontFamilyCache();
133 return item.second;
134 }
135 }
136 }
137
138 std::shared_ptr<Drawing::Typeface> typeface(dfmanager_->LoadThemeFont(familyName, OHOS_THEME_FONT, data, datalen));
139 if (!RegisterTypeface(typeface)) {
140 TEXT_LOGE("Failed to register typeface %{public}s", familyName.c_str());
141 }
142 fontCollection_->ClearFontFamilyCache();
143 return typeface;
144 }
145
ClearCaches()146 void FontCollection::ClearCaches()
147 {
148 fontCollection_->ClearFontFamilyCache();
149 }
150 } // namespace AdapterTxt
151 } // namespace Rosen
152 } // namespace OHOS
153