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