• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 
18 #include <mutex>
19 #include <unordered_map>
20 #include <vector>
21 
22 #include "include/core/SkTypes.h"
23 
24 #include "drawing_canvas_utils.h"
25 #include "drawing_font_utils.h"
26 
27 #include "text/typeface.h"
28 #include "utils/log.h"
29 #include "utils/object_mgr.h"
30 
31 static constexpr uint32_t AXIS_TAG_ZERO = 0;
32 static constexpr uint32_t AXIS_TAG_ONE = 1;
33 static constexpr uint32_t AXIS_TAG_TWO = 2;
34 static constexpr uint32_t AXIS_TAG_THREE = 3;
35 static constexpr uint32_t VARIATION_AXIS_LENGTH = 4;
36 
37 using namespace OHOS;
38 using namespace Rosen;
39 using namespace Drawing;
40 
41 static const std::string G_SYSTEM_FONT_DIR = "/system/fonts/";
42 
43 struct FontArgumentsHelper {
44     struct Coordinate {
45         uint32_t axis;
46         float value;
47     };
48 
49     int fontCollectionIndex_ = 0;
50     std::vector<Coordinate> coordinates_;
51 };
52 
CastToMemoryStream(OH_Drawing_MemoryStream * cMemoryStream)53 static MemoryStream* CastToMemoryStream(OH_Drawing_MemoryStream* cMemoryStream)
54 {
55     return reinterpret_cast<MemoryStream*>(cMemoryStream);
56 }
57 
CastToFontArgumentsHelper(const OH_Drawing_FontArguments * cFontArguments)58 static const FontArgumentsHelper* CastToFontArgumentsHelper(const OH_Drawing_FontArguments* cFontArguments)
59 {
60     return reinterpret_cast<const FontArgumentsHelper*>(cFontArguments);
61 }
62 
CastToFontArgumentsHelper(OH_Drawing_FontArguments * cFontArguments)63 static FontArgumentsHelper* CastToFontArgumentsHelper(OH_Drawing_FontArguments* cFontArguments)
64 {
65     return reinterpret_cast<FontArgumentsHelper*>(cFontArguments);
66 }
67 
CastToTypeface(const OH_Drawing_Typeface * cTypeface)68 static const Typeface* CastToTypeface(const OH_Drawing_Typeface* cTypeface)
69 {
70     return reinterpret_cast<const Typeface*>(cTypeface);
71 }
72 
ConvertToDrawingFontArguments(const FontArgumentsHelper & fontArgumentsHelper,FontArguments & fontArguments)73 static void ConvertToDrawingFontArguments(const FontArgumentsHelper& fontArgumentsHelper, FontArguments& fontArguments)
74 {
75     fontArguments.SetCollectionIndex(fontArgumentsHelper.fontCollectionIndex_);
76     fontArguments.SetVariationDesignPosition({reinterpret_cast<const FontArguments::VariationPosition::Coordinate*>(
77         fontArgumentsHelper.coordinates_.data()), fontArgumentsHelper.coordinates_.size()});
78 }
79 
RegisterAndConvertTypeface(std::shared_ptr<Typeface> typeface)80 static OH_Drawing_Typeface* RegisterAndConvertTypeface(std::shared_ptr<Typeface> typeface)
81 {
82     if (typeface == nullptr) {
83         LOGE("RegisterAndConvertTypeface: typeface nullptr.");
84         return nullptr;
85     }
86     // system font is not sent to RenderService to optimize performance.
87     if (typeface->IsCustomTypeface() && Typeface::GetTypefaceRegisterCallBack() != nullptr &&
88         !Typeface::GetTypefaceRegisterCallBack()(typeface)) {
89         LOGE("RegisterAndConvertTypeface: register typeface failed.");
90         return nullptr;
91     }
92     OH_Drawing_Typeface* drawingTypeface = reinterpret_cast<OH_Drawing_Typeface*>(typeface.get());
93     TypefaceMgr::GetInstance().Insert(drawingTypeface, typeface);
94     return drawingTypeface;
95 }
96 
OH_Drawing_TypefaceCreateDefault()97 OH_Drawing_Typeface* OH_Drawing_TypefaceCreateDefault()
98 {
99     std::shared_ptr<Typeface> typeface = DrawingFontUtils::GetZhCnTypeface();
100     if (typeface == nullptr) {
101         LOGE("OH_Drawing_TypefaceCreateDefault: create failed.");
102         return nullptr;
103     }
104     OH_Drawing_Typeface* drawingTypeface = reinterpret_cast<OH_Drawing_Typeface*>(typeface.get());
105     TypefaceMgr::GetInstance().Insert(drawingTypeface, typeface);
106     return drawingTypeface;
107 }
108 
OH_Drawing_TypefaceCreateFromFile(const char * path,int index)109 OH_Drawing_Typeface* OH_Drawing_TypefaceCreateFromFile(const char* path, int index)
110 {
111     if (path == nullptr) {
112         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
113         return nullptr;
114     }
115     std::shared_ptr<Typeface> typeface = Typeface::MakeFromFile(path, index);
116     if (typeface == nullptr) {
117         return nullptr;
118     }
119     std::string pathStr(path);
120     // system font is not sent to RenderService to optimize performance.
121     if (pathStr.substr(0, G_SYSTEM_FONT_DIR.length()) != G_SYSTEM_FONT_DIR &&
122         Drawing::Typeface::GetTypefaceRegisterCallBack() != nullptr) {
123         bool ret = Drawing::Typeface::GetTypefaceRegisterCallBack()(typeface);
124         if (!ret) {
125             LOGE("OH_Drawing_TypefaceCreateFromFile: register typeface failed.");
126             return nullptr;
127         }
128     }
129     OH_Drawing_Typeface* drawingTypeface = reinterpret_cast<OH_Drawing_Typeface*>(typeface.get());
130     TypefaceMgr::GetInstance().Insert(drawingTypeface, typeface);
131     return drawingTypeface;
132 }
133 
OH_Drawing_TypefaceCreateFromFileWithArguments(const char * path,const OH_Drawing_FontArguments * cFontArguments)134 OH_Drawing_Typeface* OH_Drawing_TypefaceCreateFromFileWithArguments(const char* path,
135     const OH_Drawing_FontArguments* cFontArguments)
136 {
137     const FontArgumentsHelper* fontArgumentsHelper = CastToFontArgumentsHelper(cFontArguments);
138     if (path == nullptr || fontArgumentsHelper == nullptr) {
139         return nullptr;
140     }
141     FontArguments fontArguments;
142     ConvertToDrawingFontArguments(*fontArgumentsHelper, fontArguments);
143     return RegisterAndConvertTypeface(Typeface::MakeFromFile(path, fontArguments));
144 }
145 
OH_Drawing_TypefaceCreateFromCurrent(const OH_Drawing_Typeface * cCurrentTypeface,const OH_Drawing_FontArguments * cFontArguments)146 OH_Drawing_Typeface* OH_Drawing_TypefaceCreateFromCurrent(const OH_Drawing_Typeface* cCurrentTypeface,
147     const OH_Drawing_FontArguments* cFontArguments)
148 {
149     const Typeface* currentTypeface = CastToTypeface(cCurrentTypeface);
150     const FontArgumentsHelper* fontArgumentsHelper = CastToFontArgumentsHelper(cFontArguments);
151     if (currentTypeface == nullptr || fontArgumentsHelper == nullptr) {
152         return nullptr;
153     }
154     FontArguments fontArguments;
155     ConvertToDrawingFontArguments(*fontArgumentsHelper, fontArguments);
156     std::shared_ptr<Typeface> typeface = currentTypeface->MakeClone(fontArguments);
157     if (typeface == nullptr || currentTypeface->GetUniqueID() == typeface->GetUniqueID()) {
158         return nullptr;
159     }
160     return RegisterAndConvertTypeface(typeface);
161 }
162 
OH_Drawing_TypefaceCreateFromStream(OH_Drawing_MemoryStream * cMemoryStream,int32_t index)163 OH_Drawing_Typeface* OH_Drawing_TypefaceCreateFromStream(OH_Drawing_MemoryStream* cMemoryStream, int32_t index)
164 {
165     if (cMemoryStream == nullptr) {
166         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
167         return nullptr;
168     }
169     std::unique_ptr<MemoryStream> memoryStream(CastToMemoryStream(cMemoryStream));
170     std::shared_ptr<Typeface> typeface = Typeface::MakeFromStream(std::move(memoryStream), index);
171     if (typeface == nullptr) {
172         return nullptr;
173     }
174     if (Drawing::Typeface::GetTypefaceRegisterCallBack() != nullptr) {
175         bool ret = Drawing::Typeface::GetTypefaceRegisterCallBack()(typeface);
176         if (!ret) {
177             LOGE("OH_Drawing_TypefaceCreateFromStream: register typeface failed.");
178             return nullptr;
179         }
180     }
181     OH_Drawing_Typeface* drawingTypeface = reinterpret_cast<OH_Drawing_Typeface*>(typeface.get());
182     TypefaceMgr::GetInstance().Insert(drawingTypeface, typeface);
183     return drawingTypeface;
184 }
185 
OH_Drawing_TypefaceDestroy(OH_Drawing_Typeface * cTypeface)186 void OH_Drawing_TypefaceDestroy(OH_Drawing_Typeface* cTypeface)
187 {
188     if (cTypeface == nullptr) {
189         return;
190     }
191     auto typeface = TypefaceMgr::GetInstance().Find(cTypeface);
192     if (Drawing::Typeface::GetTypefaceUnRegisterCallBack() != nullptr && typeface) {
193         Drawing::Typeface::GetTypefaceUnRegisterCallBack()(typeface);
194     }
195     TypefaceMgr::GetInstance().Remove(cTypeface);
196 }
197 
OH_Drawing_FontArgumentsCreate(void)198 OH_Drawing_FontArguments* OH_Drawing_FontArgumentsCreate(void)
199 {
200     return (OH_Drawing_FontArguments*)new FontArgumentsHelper();
201 }
202 
OH_Drawing_FontArgumentsAddVariation(OH_Drawing_FontArguments * cFontArguments,const char * axis,float value)203 OH_Drawing_ErrorCode OH_Drawing_FontArgumentsAddVariation(OH_Drawing_FontArguments* cFontArguments,
204     const char* axis, float value)
205 {
206     if (axis == nullptr || strlen(axis) != VARIATION_AXIS_LENGTH) {
207         return OH_DRAWING_ERROR_INVALID_PARAMETER;
208     }
209     FontArgumentsHelper* fontArgumentsHelper = CastToFontArgumentsHelper(cFontArguments);
210     if (fontArgumentsHelper == nullptr) {
211         return OH_DRAWING_ERROR_INVALID_PARAMETER;
212     }
213     fontArgumentsHelper->coordinates_.push_back(
214         {SkSetFourByteTag(axis[AXIS_TAG_ZERO], axis[AXIS_TAG_ONE], axis[AXIS_TAG_TWO], axis[AXIS_TAG_THREE]), value});
215     return OH_DRAWING_SUCCESS;
216 }
217 
OH_Drawing_FontArgumentsDestroy(OH_Drawing_FontArguments * cFontArguments)218 OH_Drawing_ErrorCode OH_Drawing_FontArgumentsDestroy(OH_Drawing_FontArguments* cFontArguments)
219 {
220     if (cFontArguments == nullptr) {
221         return OH_DRAWING_ERROR_INVALID_PARAMETER;
222     }
223     delete CastToFontArgumentsHelper(cFontArguments);
224     return OH_DRAWING_SUCCESS;
225 }