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_text_font_descriptor.h"
17
18 #include "array_mgr.h"
19 #include "font_descriptor_mgr.h"
20 #include "font_utils.h"
21 #include "text/common_utils.h"
22
23 using namespace OHOS::Rosen;
24 namespace {
CalculateDrawingStringSize(const std::string & fullName,std::u16string & utf16String)25 size_t CalculateDrawingStringSize(const std::string& fullName, std::u16string& utf16String)
26 {
27 if (fullName.empty()) {
28 return 0;
29 }
30 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
31 utf16String = converter.from_bytes(fullName);
32 return utf16String.size() * sizeof(char16_t);
33 }
34
ConvertToDrawingString(std::u16string & utf16String,OH_Drawing_String & fullNameString)35 bool ConvertToDrawingString(std::u16string& utf16String, OH_Drawing_String& fullNameString)
36 {
37 if (utf16String.empty() || fullNameString.strData == nullptr || fullNameString.strLen == 0) {
38 return false;
39 }
40 char16_t* u16Data = const_cast<char16_t*>(utf16String.c_str());
41 if (memcpy_s(fullNameString.strData, fullNameString.strLen, u16Data, fullNameString.strLen) == EOK) {
42 return true;
43 }
44 return false;
45 }
46 }
47
48 template<typename T1, typename T2>
ConvertToOriginalText(T2 * ptr)49 inline T1* ConvertToOriginalText(T2* ptr)
50 {
51 return reinterpret_cast<T1*>(ptr);
52 }
53
OH_Drawing_GetFontDescriptorByFullName(const OH_Drawing_String * fullName,OH_Drawing_SystemFontType fontType)54 OH_Drawing_FontDescriptor* OH_Drawing_GetFontDescriptorByFullName(const OH_Drawing_String* fullName,
55 OH_Drawing_SystemFontType fontType)
56 {
57 if (fullName == nullptr) {
58 return nullptr;
59 }
60 auto systemFontType = static_cast<int32_t>(fontType);
61 using namespace OHOS::Rosen::Drawing;
62 std::string fullNameString;
63 if (!ConvertToString(fullName->strData, fullName->strLen, fullNameString)) {
64 return nullptr;
65 }
66 std::shared_ptr<TextEngine::FontParser::FontDescriptor> result = nullptr;
67 FontDescriptorMgrInstance.GetFontDescSharedPtrByFullName(fullNameString, systemFontType, result);
68 if (result == nullptr) {
69 return nullptr;
70 }
71 OH_Drawing_FontDescriptor* descriptor = OH_Drawing_CreateFontDescriptor();
72 if (descriptor == nullptr) {
73 return nullptr;
74 }
75 if (!OHOS::Rosen::Drawing::CopyFontDescriptor(descriptor, *result)) {
76 OH_Drawing_DestroyFontDescriptor(descriptor);
77 return nullptr;
78 }
79 return descriptor;
80 }
81
OH_Drawing_GetSystemFontFullNamesByType(OH_Drawing_SystemFontType fontType)82 OH_Drawing_Array* OH_Drawing_GetSystemFontFullNamesByType(OH_Drawing_SystemFontType fontType)
83 {
84 auto systemFontType = static_cast<int32_t>(fontType);
85 std::unordered_set<std::string> fullNameList;
86 FontDescriptorMgrInstance.GetSystemFontFullNamesByType(systemFontType, fullNameList);
87 if (fullNameList.size() == 0) {
88 return nullptr;
89 }
90 ObjectArray* array = new (std::nothrow)ObjectArray;
91 if (array == nullptr) {
92 return nullptr;
93 }
94 OH_Drawing_String* drawingStringArray = new (std::nothrow)OH_Drawing_String[fullNameList.size()];
95 if (drawingStringArray == nullptr) {
96 delete array;
97 return nullptr;
98 }
99 size_t index = 0;
100 for (const auto& fullName : fullNameList) {
101 std::u16string utf16String;
102 size_t strByteLen = CalculateDrawingStringSize(fullName, utf16String);
103 if (strByteLen > 0) {
104 drawingStringArray[index].strData = new (std::nothrow) uint8_t[strByteLen];
105 drawingStringArray[index].strLen = static_cast<uint32_t>(strByteLen);
106 }
107
108 if (strByteLen == 0 || drawingStringArray[index].strData == nullptr ||
109 !ConvertToDrawingString(utf16String, drawingStringArray[index])) {
110 for (size_t i = 0; i <= index; ++i) {
111 delete[] drawingStringArray[i].strData;
112 }
113 delete[] drawingStringArray;
114 drawingStringArray = nullptr;
115 delete array;
116 return nullptr;
117 }
118 ++index;
119 }
120 array->addr = drawingStringArray;
121 array->num = fullNameList.size();
122 array->type = ObjectType::STRING;
123 return reinterpret_cast<OH_Drawing_Array*>(array);
124 }
125
OH_Drawing_GetSystemFontFullNameByIndex(OH_Drawing_Array * fullNameArray,size_t index)126 const OH_Drawing_String* OH_Drawing_GetSystemFontFullNameByIndex(OH_Drawing_Array* fullNameArray, size_t index)
127 {
128 ObjectArray* fullNameList = ConvertToOriginalText<ObjectArray>(fullNameArray);
129 if (fullNameList != nullptr && fullNameList->type == ObjectType::STRING &&
130 index < fullNameList->num && fullNameList->addr != nullptr) {
131 OH_Drawing_String* drawingString = ConvertToOriginalText<OH_Drawing_String>(fullNameList->addr);
132 if (drawingString != nullptr) {
133 return &drawingString[index];
134 }
135 }
136 return nullptr;
137 }
138
OH_Drawing_DestroySystemFontFullNames(OH_Drawing_Array * fullNameArray)139 void OH_Drawing_DestroySystemFontFullNames(OH_Drawing_Array* fullNameArray)
140 {
141 ObjectArray* fullNameList = ConvertToOriginalText<ObjectArray>(fullNameArray);
142 if (fullNameList == nullptr || fullNameList->type != ObjectType::STRING) {
143 return;
144 }
145 OH_Drawing_String* drawingStringArray = ConvertToOriginalText<OH_Drawing_String>(fullNameList->addr);
146 if (drawingStringArray == nullptr) {
147 return;
148 }
149 for (size_t i = 0; i < fullNameList->num; ++i) {
150 if (drawingStringArray[i].strData == nullptr) {
151 continue;
152 }
153 delete[] drawingStringArray[i].strData;
154 drawingStringArray[i].strData = nullptr;
155 }
156 delete[] drawingStringArray;
157 fullNameList->addr = nullptr;
158 fullNameList->num = 0;
159 fullNameList->type = ObjectType::INVALID;
160 delete fullNameList;
161 }