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     FontMgr* fontMgr = CastToFontMgr(drawingFontMgr);
184     if (fontMgr == nullptr) {
185         return nullptr;
186     }
187     Typeface* typeface = fontMgr->MatchFamilyStyleCharacter(familyName,
188         FontStyle(fontStyle.weight, fontStyle.width, static_cast<FontStyle::Slant>(fontStyle.slant)), bcp47, bcp47Count,
189         character);
190     if (typeface == nullptr) {
191         return nullptr;
192     }
193     std::shared_ptr<Typeface> sharedTypeface(typeface);
194     OH_Drawing_Typeface* drawingTypeface = reinterpret_cast<OH_Drawing_Typeface*>(sharedTypeface.get());
195     TypefaceMgr::GetInstance().Insert(drawingTypeface, sharedTypeface);
196     return drawingTypeface;
197 }
198 
OH_Drawing_FontStyleSetCreateTypeface(OH_Drawing_FontStyleSet * fontStyleSet,int index)199 OH_Drawing_Typeface* OH_Drawing_FontStyleSetCreateTypeface(OH_Drawing_FontStyleSet* fontStyleSet, int index)
200 {
201     if (fontStyleSet == nullptr || index < 0) {
202         return nullptr;
203     }
204     FontStyleSet* converFontStyleSet = reinterpret_cast<FontStyleSet*>(fontStyleSet);
205     auto drawingTypeface = converFontStyleSet->CreateTypeface(index);
206     if (!drawingTypeface) {
207         return nullptr;
208     }
209     std::shared_ptr<Typeface> typeface(drawingTypeface);
210     TypefaceMgr::GetInstance().Insert(drawingTypeface, typeface);
211     return reinterpret_cast<OH_Drawing_Typeface*>(drawingTypeface);
212 }
213 
OH_Drawing_FontStyleSetGetStyle(OH_Drawing_FontStyleSet * fontStyleSet,int32_t index,char ** styleName)214 OH_Drawing_FontStyleStruct OH_Drawing_FontStyleSetGetStyle(
215     OH_Drawing_FontStyleSet* fontStyleSet, int32_t index, char** styleName)
216 {
217     OH_Drawing_FontStyleStruct fontStyleStruct;
218     fontStyleStruct.weight = FONT_WEIGHT_400;
219     fontStyleStruct.width = FONT_WIDTH_NORMAL;
220     fontStyleStruct.slant = FONT_STYLE_NORMAL;
221     if (styleName == nullptr || fontStyleSet == nullptr || index < 0) {
222         return fontStyleStruct;
223     }
224     FontStyleSet* converFontStyleSet = reinterpret_cast<FontStyleSet*>(fontStyleSet);
225     if (converFontStyleSet == nullptr) {
226         *styleName = nullptr;
227         return fontStyleStruct;
228     }
229     FontStyle tempFontStyle;
230     std::string tempStringPtr;
231     converFontStyleSet->GetStyle(index, &tempFontStyle, &tempStringPtr);
232     size_t len = tempStringPtr.length() + 1;
233     char* allocatedMemoryForStyleName = (char*)(malloc(len * sizeof(char)));
234     if (allocatedMemoryForStyleName != nullptr) {
235         auto retCopy = strcpy_s(allocatedMemoryForStyleName, len, tempStringPtr.c_str());
236         if (retCopy != 0) {
237             free(allocatedMemoryForStyleName);
238             allocatedMemoryForStyleName = nullptr;
239             *styleName = nullptr;
240             return fontStyleStruct;
241         }
242     } else {
243         *styleName = nullptr;
244         return fontStyleStruct;
245     }
246     *styleName = allocatedMemoryForStyleName;
247     fontStyleStruct.weight = static_cast<OH_Drawing_FontWeight>(tempFontStyle.GetWeight());
248     fontStyleStruct.width = static_cast<OH_Drawing_FontWidth>(tempFontStyle.GetWidth());
249     fontStyleStruct.slant = static_cast<OH_Drawing_FontStyle>(tempFontStyle.GetSlant());
250     return fontStyleStruct;
251 }
252 
OH_Drawing_FontStyleSetFreeStyleName(char ** styleName)253 void OH_Drawing_FontStyleSetFreeStyleName(char** styleName)
254 {
255     if (styleName == nullptr) {
256         return;
257     }
258     if (*styleName != nullptr) {
259         free(*styleName);
260         *styleName = nullptr;
261     }
262     return;
263 }
264 
OH_Drawing_FontStyleSetMatchStyle(OH_Drawing_FontStyleSet * fontStyleSet,OH_Drawing_FontStyleStruct fontStyleStruct)265 OH_Drawing_Typeface* OH_Drawing_FontStyleSetMatchStyle(
266     OH_Drawing_FontStyleSet* fontStyleSet, OH_Drawing_FontStyleStruct fontStyleStruct)
267 {
268     FontStyleSet* converFontStyleSet = reinterpret_cast<FontStyleSet*>(fontStyleSet);
269     if (converFontStyleSet == nullptr) {
270         return nullptr;
271     }
272     auto drawingTypeface = converFontStyleSet->MatchStyle(
273         FontStyle(fontStyleStruct.weight, fontStyleStruct.width, static_cast<FontStyle::Slant>(fontStyleStruct.slant)));
274     if (!drawingTypeface) {
275         return nullptr;
276     }
277     std::shared_ptr<Typeface> typeface(drawingTypeface);
278     TypefaceMgr::GetInstance().Insert(drawingTypeface, typeface);
279     return reinterpret_cast<OH_Drawing_Typeface*>(drawingTypeface);
280 }
281 
OH_Drawing_FontStyleSetCount(OH_Drawing_FontStyleSet * fontStyleSet)282 int OH_Drawing_FontStyleSetCount(OH_Drawing_FontStyleSet* fontStyleSet)
283 {
284     FontStyleSet* converFontStyleSet = reinterpret_cast<FontStyleSet*>(fontStyleSet);
285     if (converFontStyleSet == nullptr) {
286         return 0;
287     }
288     return converFontStyleSet->Count();
289 }