• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 #include "drawing_path.h"
18 #include "drawing_rect.h"
19 
20 #ifdef USE_M133_SKIA
21 #include "src/base/SkUTF.h"
22 #else
23 #include "src/utils/SkUTF.h"
24 #endif
25 
26 #include "drawing_canvas_utils.h"
27 #include "drawing_font_utils.h"
28 #include "drawing_path.h"
29 #include "text/font.h"
30 #include "utils/log.h"
31 
32 using namespace OHOS;
33 using namespace Rosen;
34 using namespace Drawing;
35 
CastToFont(OH_Drawing_Font * cFont)36 static Font* CastToFont(OH_Drawing_Font* cFont)
37 {
38     return reinterpret_cast<Font*>(cFont);
39 }
40 
CastToFont(const OH_Drawing_Font * cFont)41 static const Font* CastToFont(const OH_Drawing_Font* cFont)
42 {
43     return reinterpret_cast<const Font*>(cFont);
44 }
45 
CastToFontFeatures(OH_Drawing_FontFeatures * fontFeatures)46 static Drawing::DrawingFontFeatures* CastToFontFeatures(OH_Drawing_FontFeatures* fontFeatures)
47 {
48     return reinterpret_cast<Drawing::DrawingFontFeatures*>(fontFeatures);
49 }
50 
CastToFontFeatures(const OH_Drawing_FontFeatures * fontFeatures)51 static const Drawing::DrawingFontFeatures* CastToFontFeatures(const OH_Drawing_FontFeatures* fontFeatures)
52 {
53     return reinterpret_cast<const Drawing::DrawingFontFeatures*>(fontFeatures);
54 }
55 
CastToTypeface(OH_Drawing_Typeface * cTypeface)56 static Typeface* CastToTypeface(OH_Drawing_Typeface* cTypeface)
57 {
58     return reinterpret_cast<Typeface*>(cTypeface);
59 }
60 
OH_Drawing_FontSetEdging(OH_Drawing_Font * cFont,OH_Drawing_FontEdging cEdging)61 void OH_Drawing_FontSetEdging(OH_Drawing_Font* cFont, OH_Drawing_FontEdging cEdging)
62 {
63     Font* font = CastToFont(cFont);
64     if (font == nullptr) {
65         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
66         return;
67     }
68     if (cEdging < FONT_EDGING_ALIAS || cEdging > FONT_EDGING_SUBPIXEL_ANTI_ALIAS) {
69         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
70         return;
71     }
72     font->SetEdging(static_cast<FontEdging>(cEdging));
73 }
74 
OH_Drawing_FontGetEdging(const OH_Drawing_Font * cFont)75 OH_Drawing_FontEdging OH_Drawing_FontGetEdging(const OH_Drawing_Font* cFont)
76 {
77     const Font* font = CastToFont(cFont);
78     if (font == nullptr) {
79         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
80         return FONT_EDGING_ALIAS;
81     }
82     return static_cast<OH_Drawing_FontEdging>(font->GetEdging());
83 }
84 
OH_Drawing_FontSetHinting(OH_Drawing_Font * cFont,OH_Drawing_FontHinting cHinting)85 void OH_Drawing_FontSetHinting(OH_Drawing_Font* cFont, OH_Drawing_FontHinting cHinting)
86 {
87     Font* font = CastToFont(cFont);
88     if (font == nullptr) {
89         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
90         return;
91     }
92     if (cHinting < FONT_HINTING_NONE || cHinting > FONT_HINTING_FULL) {
93         g_drawingErrorCode = OH_DRAWING_ERROR_PARAMETER_OUT_OF_RANGE;
94         return;
95     }
96     font->SetHinting(static_cast<FontHinting>(cHinting));
97 }
98 
OH_Drawing_FontGetHinting(const OH_Drawing_Font * cFont)99 OH_Drawing_FontHinting OH_Drawing_FontGetHinting(const OH_Drawing_Font* cFont)
100 {
101     const Font* font = CastToFont(cFont);
102     if (font == nullptr) {
103         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
104         return FONT_HINTING_NONE;
105     }
106     return static_cast<OH_Drawing_FontHinting>(font->GetHinting());
107 }
108 
OH_Drawing_FontSetForceAutoHinting(OH_Drawing_Font * cFont,bool isForceAutoHinting)109 void OH_Drawing_FontSetForceAutoHinting(OH_Drawing_Font* cFont, bool isForceAutoHinting)
110 {
111     Font* font = CastToFont(cFont);
112     if (font == nullptr) {
113         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
114         return;
115     }
116     font->SetForceAutoHinting(isForceAutoHinting);
117 }
118 
OH_Drawing_FontIsForceAutoHinting(const OH_Drawing_Font * cFont)119 bool OH_Drawing_FontIsForceAutoHinting(const OH_Drawing_Font* cFont)
120 {
121     const Font* font = CastToFont(cFont);
122     if (font == nullptr) {
123         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
124         return false;
125     }
126     return font->IsForceAutoHinting();
127 }
128 
OH_Drawing_FontSetBaselineSnap(OH_Drawing_Font * cFont,bool baselineSnap)129 void OH_Drawing_FontSetBaselineSnap(OH_Drawing_Font* cFont, bool baselineSnap)
130 {
131     Font* font = CastToFont(cFont);
132     if (font == nullptr) {
133         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
134         return;
135     }
136     font->SetBaselineSnap(baselineSnap);
137 }
138 
OH_Drawing_FontIsBaselineSnap(const OH_Drawing_Font * cFont)139 bool OH_Drawing_FontIsBaselineSnap(const OH_Drawing_Font* cFont)
140 {
141     const Font* font = CastToFont(cFont);
142     if (font == nullptr) {
143         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
144         return false;
145     }
146     return font->IsBaselineSnap();
147 }
148 
OH_Drawing_FontSetSubpixel(OH_Drawing_Font * cFont,bool isSubpixel)149 void OH_Drawing_FontSetSubpixel(OH_Drawing_Font* cFont, bool isSubpixel)
150 {
151     Font* font = CastToFont(cFont);
152     if (font == nullptr) {
153         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
154         return;
155     }
156     font->SetSubpixel(isSubpixel);
157 }
158 
OH_Drawing_FontIsSubpixel(const OH_Drawing_Font * cFont)159 bool OH_Drawing_FontIsSubpixel(const OH_Drawing_Font* cFont)
160 {
161     const Font* font = CastToFont(cFont);
162     if (font == nullptr) {
163         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
164         return false;
165     }
166     return font->IsSubpixel();
167 }
168 
OH_Drawing_FontCreate()169 OH_Drawing_Font* OH_Drawing_FontCreate()
170 {
171     Font* font = new Font();
172     font->SetTypeface(DrawingFontUtils::GetZhCnTypeface());
173     return (OH_Drawing_Font*)font;
174 }
175 
OH_Drawing_FontSetTypeface(OH_Drawing_Font * cFont,OH_Drawing_Typeface * cTypeface)176 void OH_Drawing_FontSetTypeface(OH_Drawing_Font* cFont, OH_Drawing_Typeface* cTypeface)
177 {
178     Font* font = CastToFont(cFont);
179     if (font == nullptr) {
180         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
181         return;
182     }
183     font->SetTypeface(std::shared_ptr<Typeface>{CastToTypeface(cTypeface), [](auto p) {}});
184 }
185 
OH_Drawing_FontGetTypeface(OH_Drawing_Font * cFont)186 OH_Drawing_Typeface* OH_Drawing_FontGetTypeface(OH_Drawing_Font* cFont)
187 {
188     Font* font = CastToFont(cFont);
189     if (font == nullptr) {
190         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
191         return nullptr;
192     }
193     return (OH_Drawing_Typeface*)(font->GetTypeface().get());
194 }
195 
OH_Drawing_FontSetTextSize(OH_Drawing_Font * cFont,float textSize)196 void OH_Drawing_FontSetTextSize(OH_Drawing_Font* cFont, float textSize)
197 {
198     Font* font = CastToFont(cFont);
199     if (font == nullptr) {
200         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
201         return;
202     }
203     font->SetSize(textSize);
204 }
205 
OH_Drawing_FontGetTextSize(const OH_Drawing_Font * cFont)206 float OH_Drawing_FontGetTextSize(const OH_Drawing_Font* cFont)
207 {
208     const Font* font = CastToFont(cFont);
209     if (font == nullptr) {
210         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
211         return -1.0f;
212     }
213     return font->GetSize();
214 }
215 
OH_Drawing_FontCountText(OH_Drawing_Font * cFont,const void * text,size_t byteLength,OH_Drawing_TextEncoding encoding)216 int OH_Drawing_FontCountText(OH_Drawing_Font* cFont, const void* text, size_t byteLength,
217     OH_Drawing_TextEncoding encoding)
218 {
219     if (cFont == nullptr || text == nullptr) {
220         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
221         return 0;
222     }
223     const Font* font = CastToFont(cFont);
224     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
225     if (themeFont != nullptr) {
226         font = themeFont.get();
227     }
228     return font->CountText(text, byteLength, static_cast<TextEncoding>(encoding));
229 }
230 
OH_Drawing_FontTextToGlyphs(const OH_Drawing_Font * cFont,const void * text,uint32_t byteLength,OH_Drawing_TextEncoding encoding,uint16_t * glyphs,int maxGlyphCount)231 uint32_t OH_Drawing_FontTextToGlyphs(const OH_Drawing_Font* cFont, const void* text, uint32_t byteLength,
232     OH_Drawing_TextEncoding encoding, uint16_t* glyphs, int maxGlyphCount)
233 {
234     if (cFont == nullptr || text == nullptr || glyphs == nullptr || byteLength == 0 || maxGlyphCount <= 0) {
235         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
236         return 0;
237     }
238     const Font* font = CastToFont(cFont);
239     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
240     if (themeFont != nullptr) {
241         font = themeFont.get();
242     }
243     return font->TextToGlyphs(text, byteLength,
244         static_cast<TextEncoding>(encoding), glyphs, maxGlyphCount);
245 }
246 
OH_Drawing_FontGetWidths(const OH_Drawing_Font * cFont,const uint16_t * glyphs,int count,float * widths)247 void OH_Drawing_FontGetWidths(const OH_Drawing_Font* cFont, const uint16_t* glyphs, int count, float* widths)
248 {
249     if (cFont == nullptr || glyphs == nullptr || widths == nullptr || count <= 0) {
250         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
251         return;
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     font->GetWidths(glyphs, count, widths);
259 }
260 
OH_Drawing_FontMeasureSingleCharacter(const OH_Drawing_Font * cFont,const char * str,float * textWidth)261 OH_Drawing_ErrorCode OH_Drawing_FontMeasureSingleCharacter(const OH_Drawing_Font* cFont, const char* str,
262     float* textWidth)
263 {
264     if (cFont == nullptr || str == nullptr || textWidth == nullptr) {
265         return OH_DRAWING_ERROR_INVALID_PARAMETER;
266     }
267     size_t len = strlen(str);
268     if (len == 0) {
269         return OH_DRAWING_ERROR_INVALID_PARAMETER;
270     }
271     const Font* font = CastToFont(cFont);
272     const char* currentStr = str;
273     int32_t unicode = SkUTF::NextUTF8(&currentStr, currentStr + len);
274     std::shared_ptr<Font> themeFont = DrawingFontUtils::MatchThemeFont(font, unicode);
275     if (themeFont != nullptr) {
276         font = themeFont.get();
277     }
278     *textWidth = font->MeasureSingleCharacter(unicode);
279     return OH_DRAWING_SUCCESS;
280 }
281 
OH_Drawing_FontMeasureSingleCharacterWithFeatures(const OH_Drawing_Font * font,const char * str,const OH_Drawing_FontFeatures * fontFeatures,float * textWidth)282 OH_Drawing_ErrorCode OH_Drawing_FontMeasureSingleCharacterWithFeatures(const OH_Drawing_Font* font, const char* str,
283     const OH_Drawing_FontFeatures* fontFeatures, float* textWidth)
284 {
285     const DrawingFontFeatures* features = CastToFontFeatures(fontFeatures);
286     if (font == nullptr || str == nullptr || features == nullptr ||textWidth == nullptr) {
287         return OH_DRAWING_ERROR_INVALID_PARAMETER;
288     }
289 
290     size_t len = strlen(str);
291     if (len == 0) {
292         return OH_DRAWING_ERROR_INVALID_PARAMETER;
293     }
294     const Font* drawingFont = CastToFont(font);
295     const char* currentStr = str;
296     int32_t unicode = SkUTF::NextUTF8(&currentStr, currentStr + len);
297     std::shared_ptr<Font> themeFont = DrawingFontUtils::MatchThemeFont(drawingFont, unicode);
298     if (themeFont != nullptr) {
299         drawingFont = themeFont.get();
300     }
301     int32_t utfCharLen = currentStr - str;
302     std::vector<char> strBuffer(utfCharLen + 1);
303     for (int32_t i = 0; i < utfCharLen; ++i) {
304         strBuffer[i] = str[i];
305     }
306     strBuffer[utfCharLen] = 0;
307     std::shared_ptr<Drawing::DrawingFontFeatures> featureCopy = std::make_shared<Drawing::DrawingFontFeatures>();
308     for (const auto& entry : *features) {
309         featureCopy->push_back(entry);
310     }
311     *textWidth = drawingFont->MeasureSingleCharacterWithFeatures(strBuffer.data(), unicode, featureCopy);
312     return OH_DRAWING_SUCCESS;
313 }
314 
OH_Drawing_FontFeaturesCreate(void)315 OH_Drawing_FontFeatures* OH_Drawing_FontFeaturesCreate(void)
316 {
317     Drawing::DrawingFontFeatures* features = new Drawing::DrawingFontFeatures();
318     return (OH_Drawing_FontFeatures*)features;
319 }
320 
OH_Drawing_FontFeaturesDestroy(OH_Drawing_FontFeatures * fontFeatures)321 OH_Drawing_ErrorCode OH_Drawing_FontFeaturesDestroy(OH_Drawing_FontFeatures* fontFeatures)
322 {
323     Drawing::DrawingFontFeatures* features = CastToFontFeatures(fontFeatures);
324     if (features == nullptr) {
325         return OH_DRAWING_ERROR_INVALID_PARAMETER;
326     }
327     delete features;
328     return OH_DRAWING_SUCCESS;
329 }
330 
OH_Drawing_FontFeaturesAddFeature(OH_Drawing_FontFeatures * fontFeatures,const char * name,float value)331 OH_Drawing_ErrorCode OH_Drawing_FontFeaturesAddFeature(OH_Drawing_FontFeatures* fontFeatures,
332     const char* name, float value)
333 {
334     Drawing::DrawingFontFeatures* features = CastToFontFeatures(fontFeatures);
335     if (features == nullptr || name == nullptr) {
336         return OH_DRAWING_ERROR_INVALID_PARAMETER;
337     }
338     features->push_back({{name, value}});
339     return OH_DRAWING_SUCCESS;
340 }
341 
OH_Drawing_FontMeasureText(const OH_Drawing_Font * cFont,const void * text,size_t byteLength,OH_Drawing_TextEncoding encoding,OH_Drawing_Rect * bounds,float * textWidth)342 OH_Drawing_ErrorCode OH_Drawing_FontMeasureText(const OH_Drawing_Font* cFont, const void* text, size_t byteLength,
343     OH_Drawing_TextEncoding encoding, OH_Drawing_Rect* bounds, float* textWidth)
344 {
345     if (cFont == nullptr || text == nullptr || byteLength == 0 || textWidth == nullptr) {
346         return OH_DRAWING_ERROR_INVALID_PARAMETER;
347     }
348     const Font* font = CastToFont(cFont);
349     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
350     if (themeFont != nullptr) {
351         font = themeFont.get();
352     }
353 
354     *textWidth = font->MeasureText(text, byteLength,
355         static_cast<TextEncoding>(encoding), reinterpret_cast<Drawing::Rect*>(bounds));
356     return OH_DRAWING_SUCCESS;
357 }
358 
OH_Drawing_FontMeasureTextWithBrushOrPen(const OH_Drawing_Font * cFont,const void * text,size_t byteLength,OH_Drawing_TextEncoding encoding,const OH_Drawing_Brush * brush,const OH_Drawing_Pen * pen,OH_Drawing_Rect * bounds,float * textWidth)359 OH_Drawing_ErrorCode OH_Drawing_FontMeasureTextWithBrushOrPen(const OH_Drawing_Font* cFont, const void* text,
360     size_t byteLength, OH_Drawing_TextEncoding encoding, const OH_Drawing_Brush* brush, const OH_Drawing_Pen* pen,
361     OH_Drawing_Rect* bounds, float* textWidth)
362 {
363     if (cFont == nullptr || text == nullptr || byteLength == 0 || (brush != nullptr && pen != nullptr) ||
364         textWidth == nullptr) {
365         LOGE("OH_Drawing_FontMeasureTextWithBrushOrPen: Any of font, text and textWidth is nullptr or "
366             "byteLength is 0 or brush and pen are both not nullptr.");
367         return OH_DRAWING_ERROR_INVALID_PARAMETER;
368     }
369     const Font* font = CastToFont(cFont);
370     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
371     if (themeFont != nullptr) {
372         font = themeFont.get();
373     }
374     *textWidth = font->MeasureText(text, byteLength, static_cast<TextEncoding>(encoding),
375         reinterpret_cast<Drawing::Rect*>(bounds), reinterpret_cast<const Drawing::Brush*>(brush),
376         reinterpret_cast<const Drawing::Pen*>(pen));
377     return OH_DRAWING_SUCCESS;
378 }
379 
OH_Drawing_FontGetWidthsBounds(const OH_Drawing_Font * cFont,const uint16_t * glyphs,int count,const OH_Drawing_Brush * brush,const OH_Drawing_Pen * pen,float * widths,OH_Drawing_Array * bounds)380 OH_Drawing_ErrorCode OH_Drawing_FontGetWidthsBounds(const OH_Drawing_Font* cFont, const uint16_t* glyphs, int count,
381     const OH_Drawing_Brush* brush, const OH_Drawing_Pen* pen, float* widths, OH_Drawing_Array* bounds)
382 {
383     if (cFont == nullptr || glyphs == nullptr || count <= 0 || (brush != nullptr && pen != nullptr) ||
384         (widths == nullptr && bounds == nullptr)) {
385         LOGE("OH_Drawing_FontGetWidthsBounds: Any of font and glyphs is nullptr or count is no larger than 0 or "
386             "brush and pen are both not nullptr.");
387         return OH_DRAWING_ERROR_INVALID_PARAMETER;
388     }
389     size_t size = 0;
390     OH_Drawing_Rect* rectArr = nullptr;
391     if (bounds) {
392         if (OH_Drawing_RectGetArraySize(bounds, &size) != OH_DRAWING_SUCCESS) {
393             return OH_DRAWING_ERROR_INVALID_PARAMETER;
394         }
395         if (size < static_cast<uint32_t>(count)) {
396             return OH_DRAWING_ERROR_INVALID_PARAMETER;
397         }
398         if (OH_Drawing_RectGetArrayElement(bounds, 0, &rectArr) != OH_DRAWING_SUCCESS) {
399             return OH_DRAWING_ERROR_INVALID_PARAMETER;
400         }
401         if (rectArr == nullptr) {
402             return OH_DRAWING_ERROR_INVALID_PARAMETER;
403         }
404     }
405     const Font* font = CastToFont(cFont);
406     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
407     if (themeFont != nullptr) {
408         font = themeFont.get();
409     }
410     font->GetWidthsBounds(glyphs, count, widths, reinterpret_cast<Drawing::Rect*>(rectArr),
411         reinterpret_cast<const Drawing::Brush*>(brush), reinterpret_cast<const Drawing::Pen*>(pen));
412     return OH_DRAWING_SUCCESS;
413 }
414 
OH_Drawing_FontGetPos(const OH_Drawing_Font * cFont,const uint16_t * glyphs,int count,const OH_Drawing_Point * cOrigin,OH_Drawing_Point2D * cPoints)415 OH_Drawing_ErrorCode OH_Drawing_FontGetPos(const OH_Drawing_Font* cFont, const uint16_t* glyphs, int count,
416     const OH_Drawing_Point* cOrigin, OH_Drawing_Point2D* cPoints)
417 {
418     if (cFont == nullptr || glyphs == nullptr || count <= 0 || cPoints == nullptr) {
419         LOGE("OH_Drawing_FontGetPos: Any of font, glyphs and points is nullptr or count is not larger than 0.");
420         return OH_DRAWING_ERROR_INVALID_PARAMETER;
421     }
422     const Font* font = CastToFont(cFont);
423     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
424     if (themeFont != nullptr) {
425         font = themeFont.get();
426     }
427 
428     Point* points = reinterpret_cast<Point*>(cPoints);
429     Point origin(0, 0);
430     if (cOrigin) {
431         auto tempOrigin = reinterpret_cast<const Point*>(cOrigin);
432         origin.SetX(tempOrigin->GetX());
433         origin.SetY(tempOrigin->GetY());
434     }
435     font->GetPos(glyphs, count, points, origin);
436     return OH_DRAWING_SUCCESS;
437 }
438 
OH_Drawing_FontGetSpacing(const OH_Drawing_Font * cFont,float * spacing)439 OH_Drawing_ErrorCode OH_Drawing_FontGetSpacing(const OH_Drawing_Font* cFont, float* spacing)
440 {
441     if (cFont == nullptr || spacing == nullptr) {
442         LOGE("OH_Drawing_FontGetSpacing: any of font and spacing is nullptr.");
443         return OH_DRAWING_ERROR_INVALID_PARAMETER;
444     }
445     const Font* font = CastToFont(cFont);
446     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
447     if (themeFont != nullptr) {
448         font = themeFont.get();
449     }
450     *spacing = font->GetSpacing();
451     return OH_DRAWING_SUCCESS;
452 }
453 
OH_Drawing_FontSetLinearText(OH_Drawing_Font * cFont,bool isLinearText)454 void OH_Drawing_FontSetLinearText(OH_Drawing_Font* cFont, bool isLinearText)
455 {
456     Font* font = CastToFont(cFont);
457     if (font == nullptr) {
458         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
459         return;
460     }
461     font->SetLinearMetrics(isLinearText);
462 }
463 
OH_Drawing_FontIsLinearText(const OH_Drawing_Font * cFont)464 bool OH_Drawing_FontIsLinearText(const OH_Drawing_Font* cFont)
465 {
466     const Font* font = CastToFont(cFont);
467     if (font == nullptr) {
468         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
469         return false;
470     }
471     return font->IsLinearMetrics();
472 }
473 
OH_Drawing_FontSetTextSkewX(OH_Drawing_Font * cFont,float skewX)474 void OH_Drawing_FontSetTextSkewX(OH_Drawing_Font* cFont, float skewX)
475 {
476     Font* font = CastToFont(cFont);
477     if (font == nullptr) {
478         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
479         return;
480     }
481     font->SetSkewX(skewX);
482 }
483 
OH_Drawing_FontGetTextSkewX(const OH_Drawing_Font * cFont)484 float OH_Drawing_FontGetTextSkewX(const OH_Drawing_Font* cFont)
485 {
486     const Font* font = CastToFont(cFont);
487     if (font == nullptr) {
488         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
489         return -1.0f;
490     }
491     return font->GetSkewX();
492 }
493 
OH_Drawing_FontSetFakeBoldText(OH_Drawing_Font * cFont,bool isFakeBoldText)494 void OH_Drawing_FontSetFakeBoldText(OH_Drawing_Font* cFont, bool isFakeBoldText)
495 {
496     Font* font = CastToFont(cFont);
497     if (font == nullptr) {
498         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
499         return;
500     }
501     font->SetEmbolden(isFakeBoldText);
502 }
503 
OH_Drawing_FontIsFakeBoldText(const OH_Drawing_Font * cFont)504 bool OH_Drawing_FontIsFakeBoldText(const OH_Drawing_Font* cFont)
505 {
506     const Font* font = CastToFont(cFont);
507     if (font == nullptr) {
508         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
509         return false;
510     }
511     return font->IsEmbolden();
512 }
513 
OH_Drawing_FontSetScaleX(OH_Drawing_Font * cFont,float scaleX)514 void OH_Drawing_FontSetScaleX(OH_Drawing_Font* cFont, float scaleX)
515 {
516     Font* font = CastToFont(cFont);
517     if (font == nullptr) {
518         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
519         return;
520     }
521     font->SetScaleX(scaleX);
522 }
523 
OH_Drawing_FontGetScaleX(const OH_Drawing_Font * cFont)524 float OH_Drawing_FontGetScaleX(const OH_Drawing_Font* cFont)
525 {
526     const Font* font = CastToFont(cFont);
527     if (font == nullptr) {
528         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
529         return -1.0f;
530     }
531     return font->GetScaleX();
532 }
533 
OH_Drawing_FontSetEmbeddedBitmaps(OH_Drawing_Font * cFont,bool isEmbeddedBitmaps)534 void OH_Drawing_FontSetEmbeddedBitmaps(OH_Drawing_Font* cFont, bool isEmbeddedBitmaps)
535 {
536     Font* font = CastToFont(cFont);
537     if (font == nullptr) {
538         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
539         return;
540     }
541     font->SetEmbeddedBitmaps(isEmbeddedBitmaps);
542 }
543 
OH_Drawing_FontIsEmbeddedBitmaps(const OH_Drawing_Font * cFont)544 bool OH_Drawing_FontIsEmbeddedBitmaps(const OH_Drawing_Font* cFont)
545 {
546     const Font* font = CastToFont(cFont);
547     if (font == nullptr) {
548         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
549         return false;
550     }
551     return font->IsEmbeddedBitmaps();
552 }
553 
OH_Drawing_FontDestroy(OH_Drawing_Font * cFont)554 void OH_Drawing_FontDestroy(OH_Drawing_Font* cFont)
555 {
556     if (!cFont) {
557         return;
558     }
559     delete CastToFont(cFont);
560 }
561 
OH_Drawing_FontGetMetrics(OH_Drawing_Font * cFont,OH_Drawing_Font_Metrics * cFontMetrics)562 float OH_Drawing_FontGetMetrics(OH_Drawing_Font* cFont, OH_Drawing_Font_Metrics* cFontMetrics)
563 {
564     float ret = -1;
565     const Font* font = CastToFont(cFont);
566     if (font == nullptr || cFontMetrics == nullptr) {
567         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
568         return ret;
569     }
570     FontMetrics metrics;
571     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
572     if (themeFont != nullptr) {
573         font = themeFont.get();
574     }
575     ret = font->GetMetrics(&metrics);
576 
577     cFontMetrics->flags = metrics.fFlags;
578     cFontMetrics->top = metrics.fTop;
579     cFontMetrics->ascent = metrics.fAscent;
580     cFontMetrics->descent = metrics.fDescent;
581     cFontMetrics->leading = metrics.fLeading;
582     cFontMetrics->bottom = metrics.fBottom;
583     cFontMetrics->avgCharWidth = metrics.fAvgCharWidth;
584     cFontMetrics->maxCharWidth = metrics.fMaxCharWidth;
585     cFontMetrics->xMin = metrics.fXMin;
586     cFontMetrics->xMax = metrics.fXMax;
587     cFontMetrics->xHeight = metrics.fXHeight;
588     cFontMetrics->capHeight = metrics.fCapHeight;
589     cFontMetrics->underlineThickness = metrics.fUnderlineThickness;
590     cFontMetrics->underlinePosition = metrics.fUnderlinePosition;
591     cFontMetrics->strikeoutThickness = metrics.fStrikeoutThickness;
592     cFontMetrics->strikeoutPosition = metrics.fStrikeoutPosition;
593     return ret;
594 }
595 
OH_Drawing_FontGetBounds(const OH_Drawing_Font * cFont,const uint16_t * glyphs,uint32_t count,OH_Drawing_Array * bounds)596 OH_Drawing_ErrorCode OH_Drawing_FontGetBounds(const OH_Drawing_Font* cFont, const uint16_t* glyphs, uint32_t count,
597     OH_Drawing_Array* bounds)
598 {
599     if (cFont == nullptr || glyphs == nullptr || bounds == nullptr || count == 0) {
600         return OH_DRAWING_ERROR_INVALID_PARAMETER;
601     }
602     size_t size = 0;
603     if (OH_Drawing_RectGetArraySize(bounds, &size) != OH_DRAWING_SUCCESS) {
604         return OH_DRAWING_ERROR_INVALID_PARAMETER;
605     }
606     if (size < count) {
607         return OH_DRAWING_ERROR_INVALID_PARAMETER;
608     }
609     OH_Drawing_Rect* rectArr = nullptr;
610     if (OH_Drawing_RectGetArrayElement(bounds, 0, &rectArr) != OH_DRAWING_SUCCESS) {
611         return OH_DRAWING_ERROR_INVALID_PARAMETER;
612     }
613     if (rectArr == nullptr) {
614         return OH_DRAWING_ERROR_INVALID_PARAMETER;
615     }
616     const Font* font = CastToFont(cFont);
617     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
618     if (themeFont != nullptr) {
619         font = themeFont.get();
620     }
621     font->GetWidths(glyphs, count, nullptr, reinterpret_cast<Drawing::Rect*>(rectArr));
622     return OH_DRAWING_SUCCESS;
623 }
624 
OH_Drawing_FontGetPathForGlyph(const OH_Drawing_Font * cFont,uint16_t glyph,OH_Drawing_Path * path)625 OH_Drawing_ErrorCode OH_Drawing_FontGetPathForGlyph(const OH_Drawing_Font* cFont, uint16_t glyph,
626     OH_Drawing_Path* path)
627 {
628     const Font* font = CastToFont(cFont);
629     if (font == nullptr || path == nullptr) {
630         return OH_DRAWING_ERROR_INVALID_PARAMETER;
631     }
632     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
633     if (themeFont != nullptr) {
634         font = themeFont.get();
635     }
636     if (!font->GetPathForGlyph(glyph, reinterpret_cast<Path*>(path))) {
637         return OH_DRAWING_ERROR_INVALID_PARAMETER;
638     }
639     return OH_DRAWING_SUCCESS;
640 }
641 
OH_Drawing_FontGetTextPath(const OH_Drawing_Font * cFont,const void * text,size_t byteLength,OH_Drawing_TextEncoding encoding,float x,float y,OH_Drawing_Path * path)642 OH_Drawing_ErrorCode OH_Drawing_FontGetTextPath(const OH_Drawing_Font* cFont, const void* text, size_t byteLength,
643     OH_Drawing_TextEncoding encoding, float x, float y, OH_Drawing_Path* path)
644 {
645     const Font* font = CastToFont(cFont);
646     if (font == nullptr || text == nullptr || byteLength == 0 || path == nullptr) {
647         return OH_DRAWING_ERROR_INVALID_PARAMETER;
648     }
649     std::shared_ptr<Font> themeFont = DrawingFontUtils::GetThemeFont(font);
650     if (themeFont != nullptr) {
651         font = themeFont.get();
652     }
653     font->GetTextPath(text, byteLength, static_cast<TextEncoding>(encoding), x, y, reinterpret_cast<Path*>(path));
654     return OH_DRAWING_SUCCESS;
655 }
656 
OH_Drawing_FontSetThemeFontFollowed(OH_Drawing_Font * cFont,bool followed)657 OH_Drawing_ErrorCode OH_Drawing_FontSetThemeFontFollowed(OH_Drawing_Font* cFont, bool followed)
658 {
659     Font* font = CastToFont(cFont);
660     if (font == nullptr) {
661         return OH_DRAWING_ERROR_INVALID_PARAMETER;
662     }
663     font->SetThemeFontFollowed(followed);
664     return OH_DRAWING_SUCCESS;
665 }
666 
OH_Drawing_FontIsThemeFontFollowed(const OH_Drawing_Font * cFont,bool * followed)667 OH_Drawing_ErrorCode OH_Drawing_FontIsThemeFontFollowed(const OH_Drawing_Font* cFont, bool* followed)
668 {
669     const Font* font = CastToFont(cFont);
670     if (followed == nullptr || font == nullptr) {
671         return OH_DRAWING_ERROR_INVALID_PARAMETER;
672     }
673     *followed = font->IsThemeFontFollowed();
674     return OH_DRAWING_SUCCESS;
675 }