• 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_text_blob.h"
17 
18 #include <mutex>
19 #include <unordered_map>
20 
21 #include "drawing_canvas_utils.h"
22 #include "drawing_font_utils.h"
23 
24 #include "text/text_blob_builder.h"
25 #include "utils/log.h"
26 
27 using namespace OHOS;
28 using namespace Rosen;
29 using namespace Drawing;
30 
31 static std::mutex g_textBlobLockMutex;
32 static std::unordered_map<void*, std::shared_ptr<TextBlob>> g_textBlobMap;
33 
CastToTextBlobBuilder(OH_Drawing_TextBlobBuilder * cTextBlobBuilder)34 static TextBlobBuilder* CastToTextBlobBuilder(OH_Drawing_TextBlobBuilder* cTextBlobBuilder)
35 {
36     return reinterpret_cast<TextBlobBuilder*>(cTextBlobBuilder);
37 }
38 
CastToFont(const OH_Drawing_Font * cFont)39 static const Font* CastToFont(const OH_Drawing_Font* cFont)
40 {
41     return reinterpret_cast<const Font*>(cFont);
42 }
43 
CastToTextBlob(OH_Drawing_TextBlob * cTextBlob)44 static TextBlob* CastToTextBlob(OH_Drawing_TextBlob* cTextBlob)
45 {
46     return reinterpret_cast<TextBlob*>(cTextBlob);
47 }
48 
CastToTextBlob(const OH_Drawing_TextBlob * cTextBlob)49 static const TextBlob* CastToTextBlob(const OH_Drawing_TextBlob* cTextBlob)
50 {
51     return reinterpret_cast<const TextBlob*>(cTextBlob);
52 }
53 
CastToRect(const OH_Drawing_Rect * cRect)54 static const Rect* CastToRect(const OH_Drawing_Rect* cRect)
55 {
56     return reinterpret_cast<const Rect*>(cRect);
57 }
58 
CastToPoint(const OH_Drawing_Point2D & cPoint)59 static const Point CastToPoint(const OH_Drawing_Point2D& cPoint)
60 {
61     return {cPoint.x, cPoint.y};
62 }
63 
OH_Drawing_TextBlobBuilderCreate()64 OH_Drawing_TextBlobBuilder* OH_Drawing_TextBlobBuilderCreate()
65 {
66     return (OH_Drawing_TextBlobBuilder*)new TextBlobBuilder;
67 }
68 
OH_Drawing_TextBlobCreateFromText(const void * text,size_t byteLength,const OH_Drawing_Font * cFont,OH_Drawing_TextEncoding cTextEncoding)69 OH_Drawing_TextBlob* OH_Drawing_TextBlobCreateFromText(const void* text, size_t byteLength,
70     const OH_Drawing_Font* cFont, OH_Drawing_TextEncoding cTextEncoding)
71 {
72     if (text == nullptr || cFont == nullptr) {
73         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
74         return nullptr;
75     }
76     if (cTextEncoding < TEXT_ENCODING_UTF8 || cTextEncoding > TEXT_ENCODING_GLYPH_ID) {
77         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
78         return nullptr;
79     }
80     const Font* font = CastToFont(cFont);
81     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
82     if (themeFont != nullptr) {
83         font = themeFont.get();
84     }
85     std::shared_ptr<TextBlob> textBlob = TextBlob::MakeFromText(text,
86         byteLength, *font, static_cast<TextEncoding>(cTextEncoding));
87     if (textBlob == nullptr) {
88         return nullptr;
89     }
90     std::lock_guard<std::mutex> lock(g_textBlobLockMutex);
91     g_textBlobMap.insert({textBlob.get(), textBlob});
92     return (OH_Drawing_TextBlob*)textBlob.get();
93 }
94 
OH_Drawing_TextBlobCreateFromPosText(const void * text,size_t byteLength,OH_Drawing_Point2D * cPoints,const OH_Drawing_Font * cFont,OH_Drawing_TextEncoding cTextEncoding)95 OH_Drawing_TextBlob* OH_Drawing_TextBlobCreateFromPosText(const void* text, size_t byteLength,
96     OH_Drawing_Point2D* cPoints, const OH_Drawing_Font* cFont, OH_Drawing_TextEncoding cTextEncoding)
97 {
98     if (text == nullptr || cFont == nullptr || cPoints == nullptr || byteLength == 0) {
99         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
100         return nullptr;
101     }
102     if (cTextEncoding < TEXT_ENCODING_UTF8 || cTextEncoding > TEXT_ENCODING_GLYPH_ID) {
103         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
104         return nullptr;
105     }
106     const Font* font = CastToFont(cFont);
107     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
108     if (themeFont != nullptr) {
109         font = themeFont.get();
110     }
111     const int count = font->CountText(text, byteLength, static_cast<TextEncoding>(cTextEncoding));
112     if (count <= 0) {
113         return nullptr;
114     }
115     Point* pts = new (std::nothrow) Point[count];
116     if (pts == nullptr) {
117         return nullptr;
118     }
119     for (int i = 0; i < count; ++i) {
120         pts[i] = CastToPoint(cPoints[i]);
121     }
122     std::shared_ptr<TextBlob> textBlob = TextBlob::MakeFromPosText(text, byteLength,
123         pts, *font, static_cast<TextEncoding>(cTextEncoding));
124     if (textBlob == nullptr) {
125         delete [] pts;
126         return nullptr;
127     }
128     std::lock_guard<std::mutex> lock(g_textBlobLockMutex);
129     g_textBlobMap.insert({textBlob.get(), textBlob});
130     delete [] pts;
131     return (OH_Drawing_TextBlob*)textBlob.get();
132 }
133 
OH_Drawing_TextBlobCreateFromString(const char * str,const OH_Drawing_Font * cFont,OH_Drawing_TextEncoding cTextEncoding)134 OH_Drawing_TextBlob* OH_Drawing_TextBlobCreateFromString(const char* str,
135     const OH_Drawing_Font* cFont, OH_Drawing_TextEncoding cTextEncoding)
136 {
137     if (str == nullptr || cFont == nullptr) {
138         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
139         return nullptr;
140     }
141     if (cTextEncoding < TEXT_ENCODING_UTF8 || cTextEncoding > TEXT_ENCODING_GLYPH_ID) {
142         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
143         return nullptr;
144     }
145     const Font* font = CastToFont(cFont);
146     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
147     if (themeFont != nullptr) {
148         font = themeFont.get();
149     }
150     std::shared_ptr<TextBlob> textBlob = TextBlob::MakeFromString(str,
151         *font, static_cast<TextEncoding>(cTextEncoding));
152     if (textBlob == nullptr) {
153         return nullptr;
154     }
155     std::lock_guard<std::mutex> lock(g_textBlobLockMutex);
156     g_textBlobMap.insert({textBlob.get(), textBlob});
157     return (OH_Drawing_TextBlob*)textBlob.get();
158 }
159 
OH_Drawing_TextBlobGetBounds(OH_Drawing_TextBlob * cTextBlob,OH_Drawing_Rect * cRect)160 void OH_Drawing_TextBlobGetBounds(OH_Drawing_TextBlob* cTextBlob, OH_Drawing_Rect* cRect)
161 {
162     Rect* outRect = const_cast<Rect*>(CastToRect(cRect));
163     if (outRect == nullptr) {
164         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
165         return;
166     }
167     TextBlob* textblob = CastToTextBlob(cTextBlob);
168     if (textblob == nullptr) {
169         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
170         return;
171     }
172     std::shared_ptr<Rect> rect = textblob->Bounds();
173     if (rect == nullptr) {
174         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
175         return;
176     }
177     *outRect = Rect(rect->GetLeft(), rect->GetTop(), rect->GetRight(), rect->GetBottom());
178 }
179 
OH_Drawing_TextBlobUniqueID(const OH_Drawing_TextBlob * cTextBlob)180 uint32_t OH_Drawing_TextBlobUniqueID(const OH_Drawing_TextBlob* cTextBlob)
181 {
182     if (cTextBlob == nullptr) {
183         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
184         return 0;
185     }
186     const TextBlob* textblob = CastToTextBlob(cTextBlob);
187     return textblob->UniqueID();
188 }
189 
OH_Drawing_TextBlobBuilderAllocRunPos(OH_Drawing_TextBlobBuilder * cTextBlobBuilder,const OH_Drawing_Font * cFont,int32_t count,const OH_Drawing_Rect * cRect)190 const OH_Drawing_RunBuffer* OH_Drawing_TextBlobBuilderAllocRunPos(OH_Drawing_TextBlobBuilder* cTextBlobBuilder,
191     const OH_Drawing_Font* cFont, int32_t count, const OH_Drawing_Rect* cRect)
192 {
193     if (cFont == nullptr || count <= 0) {
194         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
195         return nullptr;
196     }
197     TextBlobBuilder* textBlobBuilder = CastToTextBlobBuilder(cTextBlobBuilder);
198     if (textBlobBuilder == nullptr) {
199         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
200         return nullptr;
201     }
202     const Font* font = CastToFont(cFont);
203     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
204     if (themeFont != nullptr) {
205         font = themeFont.get();
206     }
207     return (const OH_Drawing_RunBuffer*)&textBlobBuilder->AllocRunPos(*font, count, CastToRect(cRect));
208 }
209 
OH_Drawing_TextBlobBuilderMake(OH_Drawing_TextBlobBuilder * cTextBlobBuilder)210 OH_Drawing_TextBlob* OH_Drawing_TextBlobBuilderMake(OH_Drawing_TextBlobBuilder* cTextBlobBuilder)
211 {
212     TextBlobBuilder* textBlobBuilder = CastToTextBlobBuilder(cTextBlobBuilder);
213     if (textBlobBuilder == nullptr) {
214         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
215         return nullptr;
216     }
217     std::shared_ptr<TextBlob> textBlob = textBlobBuilder->Make();
218     if (textBlob == nullptr) {
219         return nullptr;
220     }
221     std::lock_guard<std::mutex> lock(g_textBlobLockMutex);
222     g_textBlobMap.insert({textBlob.get(), textBlob});
223     return (OH_Drawing_TextBlob*)textBlob.get();
224 }
225 
OH_Drawing_TextBlobDestroy(OH_Drawing_TextBlob * cTextBlob)226 void OH_Drawing_TextBlobDestroy(OH_Drawing_TextBlob* cTextBlob)
227 {
228     std::lock_guard<std::mutex> lock(g_textBlobLockMutex);
229     auto it = g_textBlobMap.find(cTextBlob);
230     if (it == g_textBlobMap.end()) {
231         return;
232     }
233     g_textBlobMap.erase(it);
234 }
235 
OH_Drawing_TextBlobBuilderDestroy(OH_Drawing_TextBlobBuilder * cTextBlobBuilder)236 void OH_Drawing_TextBlobBuilderDestroy(OH_Drawing_TextBlobBuilder* cTextBlobBuilder)
237 {
238     if (!cTextBlobBuilder) {
239         return;
240     }
241     delete CastToTextBlobBuilder(cTextBlobBuilder);
242 }
243