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_font.h"
17
18 #include "src/utils/SkUTF.h"
19
20 #include "drawing_canvas_utils.h"
21 #include "drawing_font_utils.h"
22 #include "text/font.h"
23
24 using namespace OHOS;
25 using namespace Rosen;
26 using namespace Drawing;
27
CastToFont(OH_Drawing_Font * cFont)28 static Font* CastToFont(OH_Drawing_Font* cFont)
29 {
30 return reinterpret_cast<Font*>(cFont);
31 }
32
CastToFont(const OH_Drawing_Font * cFont)33 static const Font* CastToFont(const OH_Drawing_Font* cFont)
34 {
35 return reinterpret_cast<const Font*>(cFont);
36 }
37
CastToTypeface(OH_Drawing_Typeface * cTypeface)38 static Typeface* CastToTypeface(OH_Drawing_Typeface* cTypeface)
39 {
40 return reinterpret_cast<Typeface*>(cTypeface);
41 }
42
OH_Drawing_FontSetEdging(OH_Drawing_Font * cFont,OH_Drawing_FontEdging cEdging)43 void OH_Drawing_FontSetEdging(OH_Drawing_Font* cFont, OH_Drawing_FontEdging cEdging)
44 {
45 Font* font = CastToFont(cFont);
46 if (font == nullptr) {
47 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
48 return;
49 }
50 if (cEdging < FONT_EDGING_ALIAS || cEdging > FONT_EDGING_SUBPIXEL_ANTI_ALIAS) {
51 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
52 return;
53 }
54 font->SetEdging(static_cast<FontEdging>(cEdging));
55 }
56
OH_Drawing_FontGetEdging(const OH_Drawing_Font * cFont)57 OH_Drawing_FontEdging OH_Drawing_FontGetEdging(const OH_Drawing_Font* cFont)
58 {
59 const Font* font = CastToFont(cFont);
60 if (font == nullptr) {
61 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
62 return FONT_EDGING_ALIAS;
63 }
64 return static_cast<OH_Drawing_FontEdging>(font->GetEdging());
65 }
66
OH_Drawing_FontSetHinting(OH_Drawing_Font * cFont,OH_Drawing_FontHinting cHinting)67 void OH_Drawing_FontSetHinting(OH_Drawing_Font* cFont, OH_Drawing_FontHinting cHinting)
68 {
69 Font* font = CastToFont(cFont);
70 if (font == nullptr) {
71 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
72 return;
73 }
74 if (cHinting < FONT_HINTING_NONE || cHinting > FONT_HINTING_FULL) {
75 g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
76 return;
77 }
78 font->SetHinting(static_cast<FontHinting>(cHinting));
79 }
80
OH_Drawing_FontGetHinting(const OH_Drawing_Font * cFont)81 OH_Drawing_FontHinting OH_Drawing_FontGetHinting(const OH_Drawing_Font* cFont)
82 {
83 const Font* font = CastToFont(cFont);
84 if (font == nullptr) {
85 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
86 return FONT_HINTING_NONE;
87 }
88 return static_cast<OH_Drawing_FontHinting>(font->GetHinting());
89 }
90
OH_Drawing_FontSetForceAutoHinting(OH_Drawing_Font * cFont,bool isForceAutoHinting)91 void OH_Drawing_FontSetForceAutoHinting(OH_Drawing_Font* cFont, bool isForceAutoHinting)
92 {
93 Font* font = CastToFont(cFont);
94 if (font == nullptr) {
95 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
96 return;
97 }
98 font->SetForceAutoHinting(isForceAutoHinting);
99 }
100
OH_Drawing_FontIsForceAutoHinting(const OH_Drawing_Font * cFont)101 bool OH_Drawing_FontIsForceAutoHinting(const OH_Drawing_Font* cFont)
102 {
103 const Font* font = CastToFont(cFont);
104 if (font == nullptr) {
105 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
106 return false;
107 }
108 return font->IsForceAutoHinting();
109 }
110
OH_Drawing_FontSetBaselineSnap(OH_Drawing_Font * cFont,bool baselineSnap)111 void OH_Drawing_FontSetBaselineSnap(OH_Drawing_Font* cFont, bool baselineSnap)
112 {
113 Font* font = CastToFont(cFont);
114 if (font == nullptr) {
115 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
116 return;
117 }
118 font->SetBaselineSnap(baselineSnap);
119 }
120
OH_Drawing_FontIsBaselineSnap(const OH_Drawing_Font * cFont)121 bool OH_Drawing_FontIsBaselineSnap(const OH_Drawing_Font* cFont)
122 {
123 const Font* font = CastToFont(cFont);
124 if (font == nullptr) {
125 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
126 return false;
127 }
128 return font->IsBaselineSnap();
129 }
130
OH_Drawing_FontSetSubpixel(OH_Drawing_Font * cFont,bool isSubpixel)131 void OH_Drawing_FontSetSubpixel(OH_Drawing_Font* cFont, bool isSubpixel)
132 {
133 Font* font = CastToFont(cFont);
134 if (font == nullptr) {
135 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
136 return;
137 }
138 font->SetSubpixel(isSubpixel);
139 }
140
OH_Drawing_FontIsSubpixel(const OH_Drawing_Font * cFont)141 bool OH_Drawing_FontIsSubpixel(const OH_Drawing_Font* cFont)
142 {
143 const Font* font = CastToFont(cFont);
144 if (font == nullptr) {
145 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
146 return false;
147 }
148 return font->IsSubpixel();
149 }
150
OH_Drawing_FontCreate()151 OH_Drawing_Font* OH_Drawing_FontCreate()
152 {
153 Font* font = new Font();
154 font->SetTypeface(DrawingFontUtils::GetZhCnTypeface());
155 return (OH_Drawing_Font*)font;
156 }
157
OH_Drawing_FontSetTypeface(OH_Drawing_Font * cFont,OH_Drawing_Typeface * cTypeface)158 void OH_Drawing_FontSetTypeface(OH_Drawing_Font* cFont, OH_Drawing_Typeface* cTypeface)
159 {
160 Font* font = CastToFont(cFont);
161 if (font == nullptr) {
162 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
163 return;
164 }
165 font->SetTypeface(std::shared_ptr<Typeface>{CastToTypeface(cTypeface), [](auto p) {}});
166 }
167
OH_Drawing_FontGetTypeface(OH_Drawing_Font * cFont)168 OH_Drawing_Typeface* OH_Drawing_FontGetTypeface(OH_Drawing_Font* cFont)
169 {
170 Font* font = CastToFont(cFont);
171 if (font == nullptr) {
172 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
173 return nullptr;
174 }
175 return (OH_Drawing_Typeface*)(font->GetTypeface().get());
176 }
177
OH_Drawing_FontSetTextSize(OH_Drawing_Font * cFont,float textSize)178 void OH_Drawing_FontSetTextSize(OH_Drawing_Font* cFont, float textSize)
179 {
180 Font* font = CastToFont(cFont);
181 if (font == nullptr) {
182 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
183 return;
184 }
185 font->SetSize(textSize);
186 }
187
OH_Drawing_FontGetTextSize(const OH_Drawing_Font * cFont)188 float OH_Drawing_FontGetTextSize(const OH_Drawing_Font* cFont)
189 {
190 const Font* font = CastToFont(cFont);
191 if (font == nullptr) {
192 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
193 return -1.0f;
194 }
195 return font->GetSize();
196 }
197
OH_Drawing_FontCountText(OH_Drawing_Font * cFont,const void * text,size_t byteLength,OH_Drawing_TextEncoding encoding)198 int OH_Drawing_FontCountText(OH_Drawing_Font* cFont, const void* text, size_t byteLength,
199 OH_Drawing_TextEncoding encoding)
200 {
201 if (cFont == nullptr || text == nullptr) {
202 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
203 return 0;
204 }
205 const Font* font = CastToFont(cFont);
206 std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
207 if (themeFont != nullptr) {
208 font = themeFont.get();
209 }
210 return font->CountText(text, byteLength, static_cast<TextEncoding>(encoding));
211 }
212
OH_Drawing_FontTextToGlyphs(const OH_Drawing_Font * cFont,const void * text,uint32_t byteLength,OH_Drawing_TextEncoding encoding,uint16_t * glyphs,int maxGlyphCount)213 uint32_t OH_Drawing_FontTextToGlyphs(const OH_Drawing_Font* cFont, const void* text, uint32_t byteLength,
214 OH_Drawing_TextEncoding encoding, uint16_t* glyphs, int maxGlyphCount)
215 {
216 if (cFont == nullptr || text == nullptr || glyphs == nullptr || byteLength == 0 || maxGlyphCount <= 0) {
217 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
218 return 0;
219 }
220 const Font* font = CastToFont(cFont);
221 std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
222 if (themeFont != nullptr) {
223 font = themeFont.get();
224 }
225 return font->TextToGlyphs(text, byteLength,
226 static_cast<TextEncoding>(encoding), glyphs, maxGlyphCount);
227 }
228
OH_Drawing_FontGetWidths(const OH_Drawing_Font * cFont,const uint16_t * glyphs,int count,float * widths)229 void OH_Drawing_FontGetWidths(const OH_Drawing_Font* cFont, const uint16_t* glyphs, int count, float* widths)
230 {
231 if (cFont == nullptr || glyphs == nullptr || widths == nullptr || count <= 0) {
232 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
233 return;
234 }
235 const Font* font = CastToFont(cFont);
236 std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
237 if (themeFont != nullptr) {
238 font = themeFont.get();
239 }
240 font->GetWidths(glyphs, count, widths);
241 }
242
OH_Drawing_FontMeasureSingleCharacter(const OH_Drawing_Font * cFont,const char * str,float * textWidth)243 OH_Drawing_ErrorCode OH_Drawing_FontMeasureSingleCharacter(const OH_Drawing_Font* cFont, const char* str,
244 float* textWidth)
245 {
246 if (cFont == nullptr || str == nullptr || textWidth == nullptr) {
247 return OH_DRAWING_ERROR_INVALID_PARAMETER;
248 }
249 size_t len = strlen(str);
250 if (len == 0) {
251 return OH_DRAWING_ERROR_INVALID_PARAMETER;
252 }
253 const Font* font = CastToFont(cFont);
254 std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
255 if (themeFont != nullptr) {
256 font = themeFont.get();
257 }
258 const char* currentStr = str;
259 int32_t unicode = SkUTF::NextUTF8(¤tStr, currentStr + len);
260 *textWidth = font->MeasureSingleCharacter(unicode);
261 return OH_DRAWING_SUCCESS;
262 }
263
OH_Drawing_FontMeasureText(const OH_Drawing_Font * cFont,const void * text,size_t byteLength,OH_Drawing_TextEncoding encoding,OH_Drawing_Rect * bounds,float * textWidth)264 OH_Drawing_ErrorCode OH_Drawing_FontMeasureText(const OH_Drawing_Font* cFont, const void* text, size_t byteLength,
265 OH_Drawing_TextEncoding encoding, OH_Drawing_Rect* bounds, float* textWidth)
266 {
267 if (cFont == nullptr || text == nullptr || byteLength == 0 || textWidth == nullptr) {
268 return OH_DRAWING_ERROR_INVALID_PARAMETER;
269 }
270 const Font* font = CastToFont(cFont);
271 std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
272 if (themeFont != nullptr) {
273 font = themeFont.get();
274 }
275
276 *textWidth = font->MeasureText(text, byteLength,
277 static_cast<TextEncoding>(encoding), reinterpret_cast<Drawing::Rect*>(bounds));
278 return OH_DRAWING_SUCCESS;
279 }
280
OH_Drawing_FontSetLinearText(OH_Drawing_Font * cFont,bool isLinearText)281 void OH_Drawing_FontSetLinearText(OH_Drawing_Font* cFont, bool isLinearText)
282 {
283 Font* font = CastToFont(cFont);
284 if (font == nullptr) {
285 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
286 return;
287 }
288 font->SetLinearMetrics(isLinearText);
289 }
290
OH_Drawing_FontIsLinearText(const OH_Drawing_Font * cFont)291 bool OH_Drawing_FontIsLinearText(const OH_Drawing_Font* cFont)
292 {
293 const Font* font = CastToFont(cFont);
294 if (font == nullptr) {
295 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
296 return false;
297 }
298 return font->IsLinearMetrics();
299 }
300
OH_Drawing_FontSetTextSkewX(OH_Drawing_Font * cFont,float skewX)301 void OH_Drawing_FontSetTextSkewX(OH_Drawing_Font* cFont, float skewX)
302 {
303 Font* font = CastToFont(cFont);
304 if (font == nullptr) {
305 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
306 return;
307 }
308 font->SetSkewX(skewX);
309 }
310
OH_Drawing_FontGetTextSkewX(const OH_Drawing_Font * cFont)311 float OH_Drawing_FontGetTextSkewX(const OH_Drawing_Font* cFont)
312 {
313 const Font* font = CastToFont(cFont);
314 if (font == nullptr) {
315 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
316 return -1.0f;
317 }
318 return font->GetSkewX();
319 }
320
OH_Drawing_FontSetFakeBoldText(OH_Drawing_Font * cFont,bool isFakeBoldText)321 void OH_Drawing_FontSetFakeBoldText(OH_Drawing_Font* cFont, bool isFakeBoldText)
322 {
323 Font* font = CastToFont(cFont);
324 if (font == nullptr) {
325 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
326 return;
327 }
328 font->SetEmbolden(isFakeBoldText);
329 }
330
OH_Drawing_FontIsFakeBoldText(const OH_Drawing_Font * cFont)331 bool OH_Drawing_FontIsFakeBoldText(const OH_Drawing_Font* cFont)
332 {
333 const Font* font = CastToFont(cFont);
334 if (font == nullptr) {
335 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
336 return false;
337 }
338 return font->IsEmbolden();
339 }
340
OH_Drawing_FontSetScaleX(OH_Drawing_Font * cFont,float scaleX)341 void OH_Drawing_FontSetScaleX(OH_Drawing_Font* cFont, float scaleX)
342 {
343 Font* font = CastToFont(cFont);
344 if (font == nullptr) {
345 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
346 return;
347 }
348 font->SetScaleX(scaleX);
349 }
350
OH_Drawing_FontGetScaleX(const OH_Drawing_Font * cFont)351 float OH_Drawing_FontGetScaleX(const OH_Drawing_Font* cFont)
352 {
353 const Font* font = CastToFont(cFont);
354 if (font == nullptr) {
355 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
356 return -1.0f;
357 }
358 return font->GetScaleX();
359 }
360
OH_Drawing_FontSetEmbeddedBitmaps(OH_Drawing_Font * cFont,bool isEmbeddedBitmaps)361 void OH_Drawing_FontSetEmbeddedBitmaps(OH_Drawing_Font* cFont, bool isEmbeddedBitmaps)
362 {
363 Font* font = CastToFont(cFont);
364 if (font == nullptr) {
365 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
366 return;
367 }
368 font->SetEmbeddedBitmaps(isEmbeddedBitmaps);
369 }
370
OH_Drawing_FontIsEmbeddedBitmaps(const OH_Drawing_Font * cFont)371 bool OH_Drawing_FontIsEmbeddedBitmaps(const OH_Drawing_Font* cFont)
372 {
373 const Font* font = CastToFont(cFont);
374 if (font == nullptr) {
375 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
376 return false;
377 }
378 return font->IsEmbeddedBitmaps();
379 }
380
OH_Drawing_FontDestroy(OH_Drawing_Font * cFont)381 void OH_Drawing_FontDestroy(OH_Drawing_Font* cFont)
382 {
383 if (!cFont) {
384 return;
385 }
386 delete CastToFont(cFont);
387 }
388
OH_Drawing_FontGetMetrics(OH_Drawing_Font * cFont,OH_Drawing_Font_Metrics * cFontMetrics)389 float OH_Drawing_FontGetMetrics(OH_Drawing_Font* cFont, OH_Drawing_Font_Metrics* cFontMetrics)
390 {
391 float ret = -1;
392 const Font* font = CastToFont(cFont);
393 if (font == nullptr || cFontMetrics == nullptr) {
394 g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
395 return ret;
396 }
397 FontMetrics metrics;
398 std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
399 if (themeFont != nullptr) {
400 font = themeFont.get();
401 }
402 ret = font->GetMetrics(&metrics);
403
404 cFontMetrics->top = metrics.fTop;
405 cFontMetrics->ascent = metrics.fAscent;
406 cFontMetrics->descent = metrics.fDescent;
407 cFontMetrics->leading = metrics.fLeading;
408 cFontMetrics->bottom = metrics.fBottom;
409 return ret;
410 }
411
OH_Drawing_FontSetThemeFontFollowed(OH_Drawing_Font * cFont,bool followed)412 OH_Drawing_ErrorCode OH_Drawing_FontSetThemeFontFollowed(OH_Drawing_Font* cFont, bool followed)
413 {
414 Font* font = CastToFont(cFont);
415 if (font == nullptr) {
416 return OH_DRAWING_ERROR_INVALID_PARAMETER;
417 }
418 font->SetThemeFontFollowed(followed);
419 return OH_DRAWING_SUCCESS;
420 }
421
OH_Drawing_FontIsThemeFontFollowed(const OH_Drawing_Font * cFont,bool * followed)422 OH_Drawing_ErrorCode OH_Drawing_FontIsThemeFontFollowed(const OH_Drawing_Font* cFont, bool* followed)
423 {
424 const Font* font = CastToFont(cFont);
425 if (followed == nullptr || font == nullptr) {
426 return OH_DRAWING_ERROR_INVALID_PARAMETER;
427 }
428 *followed = font->IsThemeFontFollowed();
429 return OH_DRAWING_SUCCESS;
430 }