• 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_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(&currentStr, 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 }