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 "drawing_typeface.h"
17 #include "drawing_font_mgr.h"
18 #include <mutex>
19 #include <unordered_map>
20 #include <securec.h>
21
22 #include "text/font_mgr.h"
23 #include "text/typeface.h"
24 #include "utils/object_mgr.h"
25
26 using namespace OHOS;
27 using namespace Rosen;
28 using namespace Drawing;
29
30 static std::mutex g_fontMgrLockMutex;
31 static std::mutex g_fontStyleSetLockMutex;
32 static std::unordered_map<void*, std::shared_ptr<FontMgr>> g_fontMgrMap;
33 static std::unordered_map<void*, std::shared_ptr<FontStyleSet>> g_fontStyleSetMap;
34
CastToFontMgr(OH_Drawing_FontMgr * drawingFontMgr)35 static FontMgr* CastToFontMgr(OH_Drawing_FontMgr* drawingFontMgr)
36 {
37 if (drawingFontMgr == nullptr) {
38 return nullptr;
39 }
40 FontMgr* fontMgr = reinterpret_cast<FontMgr*>(drawingFontMgr);
41 auto it = g_fontMgrMap.find(fontMgr);
42 if (it != g_fontMgrMap.end()) {
43 return it->second.get();
44 }
45 return nullptr;
46 }
47
OH_Drawing_FontMgrCreate()48 OH_Drawing_FontMgr* OH_Drawing_FontMgrCreate()
49 {
50 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
51 std::lock_guard<std::mutex> lock(g_fontMgrLockMutex);
52 g_fontMgrMap.insert({ fontMgr.get(), fontMgr });
53 return (OH_Drawing_FontMgr*)fontMgr.get();
54 }
55
OH_Drawing_FontMgrDestroy(OH_Drawing_FontMgr * drawingFontMgr)56 void OH_Drawing_FontMgrDestroy(OH_Drawing_FontMgr* drawingFontMgr)
57 {
58 if (drawingFontMgr == nullptr) {
59 return;
60 }
61 std::lock_guard<std::mutex> lock(g_fontMgrLockMutex);
62 g_fontMgrMap.erase(drawingFontMgr);
63 }
64
OH_Drawing_FontMgrGetFamilyCount(OH_Drawing_FontMgr * drawingFontMgr)65 int OH_Drawing_FontMgrGetFamilyCount(OH_Drawing_FontMgr* drawingFontMgr)
66 {
67 FontMgr* fontMgr = CastToFontMgr(drawingFontMgr);
68 if (fontMgr == nullptr) {
69 return 0;
70 }
71 return fontMgr->CountFamilies();
72 }
73
CopyStrData(char ** destination,const std::string & source)74 static bool CopyStrData(char** destination, const std::string& source)
75 {
76 if (source.empty()) {
77 return false;
78 }
79 size_t destinationSize = source.size() + 1;
80 *destination = new (std::nothrow) char[destinationSize];
81 if (*destination == nullptr) {
82 return false;
83 }
84 auto retCopy = strcpy_s(*destination, destinationSize, source.c_str());
85 if (retCopy != 0) {
86 delete[] *destination;
87 *destination = nullptr;
88 return false;
89 }
90 return true;
91 }
92
OH_Drawing_FontMgrGetFamilyName(OH_Drawing_FontMgr * drawingFontMgr,int index)93 char* OH_Drawing_FontMgrGetFamilyName(OH_Drawing_FontMgr* drawingFontMgr, int index)
94 {
95 FontMgr* fontMgr = CastToFontMgr(drawingFontMgr);
96 if (fontMgr == nullptr || index < 0) {
97 return nullptr;
98 }
99 std::string strFamilyName = "";
100 fontMgr->GetFamilyName(index, strFamilyName);
101 char* familyName = nullptr;
102 auto ret = CopyStrData(&familyName, strFamilyName);
103 if (!ret) {
104 return nullptr;
105 }
106 return familyName;
107 }
108
OH_Drawing_FontMgrDestroyFamilyName(char * familyName)109 void OH_Drawing_FontMgrDestroyFamilyName(char* familyName)
110 {
111 if (familyName == nullptr) {
112 return;
113 }
114 delete[] familyName;
115 }
116
OH_Drawing_FontMgrCreateFontStyleSet(OH_Drawing_FontMgr * drawingFontMgr,int index)117 OH_Drawing_FontStyleSet* OH_Drawing_FontMgrCreateFontStyleSet(OH_Drawing_FontMgr* drawingFontMgr, int index)
118 {
119 FontMgr* fontMgr = CastToFontMgr(drawingFontMgr);
120 if (fontMgr == nullptr || index < 0) {
121 return nullptr;
122 }
123 FontStyleSet* fontStyleSet = fontMgr->CreateStyleSet(index);
124 if (fontStyleSet == nullptr) {
125 return nullptr;
126 }
127 std::shared_ptr<FontStyleSet> sharedFontStyleSet(fontStyleSet);
128 std::lock_guard<std::mutex> lock(g_fontStyleSetLockMutex);
129 g_fontStyleSetMap.insert({ sharedFontStyleSet.get(), sharedFontStyleSet });
130 return (OH_Drawing_FontStyleSet*)sharedFontStyleSet.get();
131 }
132
OH_Drawing_FontMgrDestroyFontStyleSet(OH_Drawing_FontStyleSet * drawingFontStyleSet)133 void OH_Drawing_FontMgrDestroyFontStyleSet(OH_Drawing_FontStyleSet* drawingFontStyleSet)
134 {
135 if (drawingFontStyleSet == nullptr) {
136 return;
137 }
138 std::lock_guard<std::mutex> lock(g_fontStyleSetLockMutex);
139 g_fontStyleSetMap.erase(drawingFontStyleSet);
140 }
141
OH_Drawing_FontMgrMatchFamily(OH_Drawing_FontMgr * drawingFontMgr,const char * familyName)142 OH_Drawing_FontStyleSet* OH_Drawing_FontMgrMatchFamily(OH_Drawing_FontMgr* drawingFontMgr, const char* familyName)
143 {
144 if (familyName == nullptr) {
145 return nullptr;
146 }
147 FontMgr* fontMgr = CastToFontMgr(drawingFontMgr);
148 if (fontMgr == nullptr) {
149 return nullptr;
150 }
151 FontStyleSet* fontStyleSet = fontMgr->MatchFamily(familyName);
152 if (fontStyleSet == nullptr) {
153 return nullptr;
154 }
155 std::shared_ptr<FontStyleSet> sharedFontStyleSet(fontStyleSet);
156 std::lock_guard<std::mutex> lock(g_fontStyleSetLockMutex);
157 g_fontStyleSetMap.insert({ sharedFontStyleSet.get(), sharedFontStyleSet });
158 return (OH_Drawing_FontStyleSet*)sharedFontStyleSet.get();
159 }
160
OH_Drawing_FontMgrMatchFamilyStyle(OH_Drawing_FontMgr * drawingFontMgr,const char * familyName,OH_Drawing_FontStyleStruct fontStyle)161 OH_Drawing_Typeface* OH_Drawing_FontMgrMatchFamilyStyle(
162 OH_Drawing_FontMgr* drawingFontMgr, const char* familyName, OH_Drawing_FontStyleStruct fontStyle)
163 {
164 FontMgr* fontMgr = CastToFontMgr(drawingFontMgr);
165 if (fontMgr == nullptr) {
166 return nullptr;
167 }
168 Typeface* typeface = fontMgr->MatchFamilyStyle(
169 familyName, FontStyle(fontStyle.weight, fontStyle.width, static_cast<FontStyle::Slant>(fontStyle.slant)));
170 if (typeface == nullptr) {
171 return nullptr;
172 }
173 std::shared_ptr<Typeface> sharedTypeface(typeface);
174 OH_Drawing_Typeface* drawingTypeface = reinterpret_cast<OH_Drawing_Typeface*>(sharedTypeface.get());
175 TypefaceMgr::GetInstance().Insert(drawingTypeface, sharedTypeface);
176 return drawingTypeface;
177 }
178
OH_Drawing_FontMgrMatchFamilyStyleCharacter(OH_Drawing_FontMgr * drawingFontMgr,const char * familyName,OH_Drawing_FontStyleStruct fontStyle,const char * bcp47[],int bcp47Count,int32_t character)179 OH_Drawing_Typeface* OH_Drawing_FontMgrMatchFamilyStyleCharacter(OH_Drawing_FontMgr* drawingFontMgr,
180 const char* familyName, OH_Drawing_FontStyleStruct fontStyle, const char* bcp47[], int bcp47Count,
181 int32_t character)
182 {
183 if (bcp47 == nullptr || bcp47Count <= 0) {
184 return nullptr;
185 }
186 FontMgr* fontMgr = CastToFontMgr(drawingFontMgr);
187 if (fontMgr == nullptr) {
188 return nullptr;
189 }
190 Typeface* typeface = fontMgr->MatchFamilyStyleCharacter(familyName,
191 FontStyle(fontStyle.weight, fontStyle.width, static_cast<FontStyle::Slant>(fontStyle.slant)), bcp47, bcp47Count,
192 character);
193 if (typeface == nullptr) {
194 return nullptr;
195 }
196 std::shared_ptr<Typeface> sharedTypeface(typeface);
197 OH_Drawing_Typeface* drawingTypeface = reinterpret_cast<OH_Drawing_Typeface*>(sharedTypeface.get());
198 TypefaceMgr::GetInstance().Insert(drawingTypeface, sharedTypeface);
199 return drawingTypeface;
200 }
201
OH_Drawing_FontStyleSetCreateTypeface(OH_Drawing_FontStyleSet * fontStyleSet,int index)202 OH_Drawing_Typeface* OH_Drawing_FontStyleSetCreateTypeface(OH_Drawing_FontStyleSet* fontStyleSet, int index)
203 {
204 if (fontStyleSet == nullptr || index < 0) {
205 return nullptr;
206 }
207 FontStyleSet* converFontStyleSet = reinterpret_cast<FontStyleSet*>(fontStyleSet);
208 auto drawingTypeface = converFontStyleSet->CreateTypeface(index);
209 if (!drawingTypeface) {
210 return nullptr;
211 }
212 std::shared_ptr<Typeface> typeface(drawingTypeface);
213 TypefaceMgr::GetInstance().Insert(drawingTypeface, typeface);
214 return reinterpret_cast<OH_Drawing_Typeface*>(drawingTypeface);
215 }
216
OH_Drawing_FontStyleSetGetStyle(OH_Drawing_FontStyleSet * fontStyleSet,int32_t index,char ** styleName)217 OH_Drawing_FontStyleStruct OH_Drawing_FontStyleSetGetStyle(
218 OH_Drawing_FontStyleSet* fontStyleSet, int32_t index, char** styleName)
219 {
220 OH_Drawing_FontStyleStruct fontStyleStruct;
221 fontStyleStruct.weight = FONT_WEIGHT_400;
222 fontStyleStruct.width = FONT_WIDTH_NORMAL;
223 fontStyleStruct.slant = FONT_STYLE_NORMAL;
224 if (styleName == nullptr || fontStyleSet == nullptr || index < 0) {
225 return fontStyleStruct;
226 }
227 FontStyleSet* converFontStyleSet = reinterpret_cast<FontStyleSet*>(fontStyleSet);
228 if (converFontStyleSet == nullptr) {
229 *styleName = nullptr;
230 return fontStyleStruct;
231 }
232 FontStyle tempFontStyle;
233 std::string tempStringPtr;
234 converFontStyleSet->GetStyle(index, &tempFontStyle, &tempStringPtr);
235 size_t len = tempStringPtr.length() + 1;
236 char* allocatedMemoryForStyleName = (char*)(malloc(len * sizeof(char)));
237 if (allocatedMemoryForStyleName != nullptr) {
238 auto retCopy = strcpy_s(allocatedMemoryForStyleName, len, tempStringPtr.c_str());
239 if (retCopy != 0) {
240 free(allocatedMemoryForStyleName);
241 allocatedMemoryForStyleName = nullptr;
242 *styleName = nullptr;
243 return fontStyleStruct;
244 }
245 } else {
246 *styleName = nullptr;
247 return fontStyleStruct;
248 }
249 *styleName = allocatedMemoryForStyleName;
250 fontStyleStruct.weight = static_cast<OH_Drawing_FontWeight>(tempFontStyle.GetWeight());
251 fontStyleStruct.width = static_cast<OH_Drawing_FontWidth>(tempFontStyle.GetWidth());
252 fontStyleStruct.slant = static_cast<OH_Drawing_FontStyle>(tempFontStyle.GetSlant());
253 return fontStyleStruct;
254 }
255
OH_Drawing_FontStyleSetFreeStyleName(char ** styleName)256 void OH_Drawing_FontStyleSetFreeStyleName(char** styleName)
257 {
258 if (styleName == nullptr) {
259 return;
260 }
261 if (*styleName != nullptr) {
262 free(*styleName);
263 *styleName = nullptr;
264 }
265 return;
266 }
267
OH_Drawing_FontStyleSetMatchStyle(OH_Drawing_FontStyleSet * fontStyleSet,OH_Drawing_FontStyleStruct fontStyleStruct)268 OH_Drawing_Typeface* OH_Drawing_FontStyleSetMatchStyle(
269 OH_Drawing_FontStyleSet* fontStyleSet, OH_Drawing_FontStyleStruct fontStyleStruct)
270 {
271 FontStyleSet* converFontStyleSet = reinterpret_cast<FontStyleSet*>(fontStyleSet);
272 if (converFontStyleSet == nullptr) {
273 return nullptr;
274 }
275 auto drawingTypeface = converFontStyleSet->MatchStyle(
276 FontStyle(fontStyleStruct.weight, fontStyleStruct.width, static_cast<FontStyle::Slant>(fontStyleStruct.slant)));
277 if (!drawingTypeface) {
278 return nullptr;
279 }
280 std::shared_ptr<Typeface> typeface(drawingTypeface);
281 TypefaceMgr::GetInstance().Insert(drawingTypeface, typeface);
282 return reinterpret_cast<OH_Drawing_Typeface*>(drawingTypeface);
283 }
284
OH_Drawing_FontStyleSetCount(OH_Drawing_FontStyleSet * fontStyleSet)285 int OH_Drawing_FontStyleSetCount(OH_Drawing_FontStyleSet* fontStyleSet)
286 {
287 FontStyleSet* converFontStyleSet = reinterpret_cast<FontStyleSet*>(fontStyleSet);
288 if (converFontStyleSet == nullptr) {
289 return 0;
290 }
291 return converFontStyleSet->Count();
292 }