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