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 }