• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 <filesystem>
17 #include "gtest/gtest.h"
18 #include "drawing_bitmap.h"
19 #include "drawing_font_collection.h"
20 #include "drawing_rect.h"
21 #include "drawing_text_global.h"
22 #include "drawing_text_line.h"
23 #include "drawing_text_typography.h"
24 
25 using namespace testing;
26 using namespace testing::ext;
27 
28 namespace {
ExistNotdef()29 bool ExistNotdef()
30 {
31     return std::filesystem::exists("/system/fonts/HarmonyOS_Sans_Notdef.ttf");
32 }
33 
ExistNotoSans()34 bool ExistNotoSans()
35 {
36     return std::filesystem::exists("/system/fonts/NotoSans[wdth,wght].ttf");
37 }
38 } // namespace
39 
40 namespace OHOS {
41 namespace Rosen {
42 namespace {
43     const int NUM_1 = 1;
44     const int NUM_3 = 3;
45     const int NUM_100 = 100;
46 }
47 
48 class NativeUndefinedGlyphDisplayTest : public testing::Test {
49 public:
50     OH_Drawing_Typography* PrepareCreateTypography(
51         const std::string& text, const char** fontFamilies = nullptr, int fontCount = 0);
52     void BoundsResult(OH_Drawing_Typography* typography, const float rectResult[][4], size_t size);
53 
54     static constexpr const char* text_ = "Hello 测 World \uffff\n!@#$%^&*~(){\uffff\uffff}[]90 - = ,.\n\uffff"
55                                          "testlp\uffff试\uffff Drawing\uffff";
56     static constexpr const char* noGlyphText_ = "\uffff";
57     static constexpr float defaultResult_[][4] = { { 2.0, 2.0, 206.63979, 29.0 }, { 1.0, 5.0, 388.10962, 37.0 },
58         { 0, 8.0, 319.4397, 42.0 } };
59     static constexpr float tofuResult_[][4] = { { 2.0, 2.0, 228.63979, 29.0 }, { 1.0, 5.0, 388.10962, 37.0 },
60         { 8.0, 8.0, 341.4397, 42.0 } };
61     static constexpr float notoResult_[][4] = { { 2.0, 2.0, 232.20976, 29.0 }, { 2.0, 5.0, 388.43961, 33.0 },
62         { 8.0, 8.0, 347.76962, 42.0 } };
63     static constexpr float noGlyphTofuResult_[][4] = { { 8.0, 0, 22.0, 22.0 } };
64     static constexpr float noGlyphDefaultResult_[][4] = { { 0, 0, 0, 0 } };
65     static constexpr float noGlyphNotoResult_[][4] = { { 0, 0, 0, 0 } };
66 };
67 
PrepareCreateTypography(const std::string & text,const char ** fontFamilies,int fontCount)68 OH_Drawing_Typography* NativeUndefinedGlyphDisplayTest::PrepareCreateTypography(
69     const std::string& text, const char** fontFamilies, int fontCount)
70 {
71     double maxWidth = 500.0;
72     OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle();
73     EXPECT_NE(typoStyle, nullptr);
74     OH_Drawing_TextStyle* txtStyle = OH_Drawing_CreateTextStyle();
75     EXPECT_NE(txtStyle, nullptr);
76     OH_Drawing_SetTextStyleFontFamilies(txtStyle, fontCount, fontFamilies);
77     OH_Drawing_FontCollection* fontCollection = OH_Drawing_GetFontCollectionGlobalInstance();
78     EXPECT_NE(fontCollection, nullptr);
79     OH_Drawing_TypographyCreate* handler = OH_Drawing_CreateTypographyHandler(typoStyle, fontCollection);
80     EXPECT_NE(handler, nullptr);
81     OH_Drawing_SetTextStyleColor(txtStyle, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0x00));
82     double fontSize = 30;
83     OH_Drawing_SetTextStyleFontSize(txtStyle, fontSize);
84     OH_Drawing_SetTextStyleFontWeight(txtStyle, FONT_WEIGHT_400);
85     OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle);
86     OH_Drawing_TypographyHandlerAddText(handler, text.c_str());
87     OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(handler);
88     EXPECT_NE(typography, nullptr);
89     OH_Drawing_TypographyLayout(typography, maxWidth);
90     OH_Drawing_DestroyTypographyStyle(typoStyle);
91     OH_Drawing_DestroyTextStyle(txtStyle);
92     OH_Drawing_DestroyTypographyHandler(handler);
93     return typography;
94 }
95 
BoundsResult(OH_Drawing_Typography * typography,const float rectResult[][4],size_t size)96 void NativeUndefinedGlyphDisplayTest::BoundsResult(
97     OH_Drawing_Typography* typography, const float rectResult[][4], size_t size)
98 {
99     OH_Drawing_Array* textLines = OH_Drawing_TypographyGetTextLines(typography);
100     size_t arraySize = OH_Drawing_GetDrawingArraySize(textLines);
101     EXPECT_EQ(size, arraySize);
102     for (size_t index = 0; index < arraySize; index++) {
103         OH_Drawing_TextLine* textLine = OH_Drawing_GetTextLineByIndex(textLines, index);
104         OH_Drawing_Rect* rect = OH_Drawing_TextLineGetImageBounds(textLine);
105         EXPECT_FLOAT_EQ(rectResult[index][0], OH_Drawing_RectGetLeft(rect));
106         EXPECT_FLOAT_EQ(rectResult[index][1], OH_Drawing_RectGetTop(rect));
107         // 2 is the index of right
108         EXPECT_FLOAT_EQ(rectResult[index][2], OH_Drawing_RectGetRight(rect));
109         // 3 is the index of bottom
110         EXPECT_FLOAT_EQ(rectResult[index][3], OH_Drawing_RectGetBottom(rect));
111         OH_Drawing_RectDestroy(rect);
112         OH_Drawing_DestroyTextLine(textLine);
113     }
114     OH_Drawing_DestroyTextLines(textLines);
115 }
116 
117 /*
118  * @tc.number: SUB_GRAPHIC_GRAPHIC_2D_SetTextUndefinedGlyphDisplay_001
119  * @tc.name  : OHDrawingSetTextUndefinedGlyphDisplay001
120  * @tc.desc  : Test undefined glyph display use tofu
121  * @tc.size  : MediumTest
122  * @tc.type  : Function
123  * @tc.level : Level 0
124  */
125 HWTEST_F(NativeUndefinedGlyphDisplayTest, OHDrawingSetTextUndefinedGlyphDisplay001, Function | MediumTest | Level0)
126 {
127     OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_TOFU);
128     OH_Drawing_Typography* typography = PrepareCreateTypography(text_);
129     EXPECT_NE(typography, nullptr);
130     if (ExistNotdef()) {
131         BoundsResult(typography, tofuResult_, NUM_3);
132     } else {
133         BoundsResult(typography, defaultResult_, NUM_3);
134     }
135     OH_Drawing_DestroyTypography(typography);
136 }
137 
138 /*
139  * @tc.number: SUB_GRAPHIC_GRAPHIC_2D_SetTextUndefinedGlyphDisplay_002
140  * @tc.name  : OHDrawingSetTextUndefinedGlyphDisplay002
141  * @tc.desc  : Test undefined glyph display use default
142  * @tc.size  : MediumTest
143  * @tc.type  : Function
144  * @tc.level : Level 0
145  */
146 HWTEST_F(NativeUndefinedGlyphDisplayTest, OHDrawingSetTextUndefinedGlyphDisplay002, Function | MediumTest | Level0)
147 {
148     OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_DEFAULT);
149     OH_Drawing_Typography* typography = PrepareCreateTypography(text_);
150     EXPECT_NE(typography, nullptr);
151     BoundsResult(typography, defaultResult_, NUM_3);
152     OH_Drawing_DestroyTypography(typography);
153 }
154 
155 /*
156  * @tc.number: SUB_GRAPHIC_GRAPHIC_2D_SetTextUndefinedGlyphDisplay_003
157  * @tc.name  : OHDrawingSetTextUndefinedGlyphDisplay003
158  * @tc.desc  : Test undefined glyph display use invalid input
159  * @tc.size  : MediumTest
160  * @tc.type  : Function
161  * @tc.level : Level 0
162  */
163 HWTEST_F(NativeUndefinedGlyphDisplayTest, OHDrawingSetTextUndefinedGlyphDisplay003, Function | MediumTest | Level0)
164 {
165     OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_DEFAULT);
166     OH_Drawing_SetTextUndefinedGlyphDisplay(static_cast<OH_Drawing_TextUndefinedGlyphDisplay>(NUM_100));
167     OH_Drawing_Typography* defaultTypography = PrepareCreateTypography(text_);
168     EXPECT_NE(defaultTypography, nullptr);
169     BoundsResult(defaultTypography, defaultResult_, NUM_3);
170     OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_TOFU);
171     OH_Drawing_SetTextUndefinedGlyphDisplay(static_cast<OH_Drawing_TextUndefinedGlyphDisplay>(NUM_100));
172     OH_Drawing_Typography* tofuTypography = PrepareCreateTypography(text_);
173     EXPECT_NE(tofuTypography, nullptr);
174     if (ExistNotdef()) {
175         BoundsResult(tofuTypography, tofuResult_, NUM_3);
176     } else {
177         BoundsResult(tofuTypography, defaultResult_, NUM_3);
178     }
179     OH_Drawing_DestroyTypography(defaultTypography);
180     OH_Drawing_DestroyTypography(tofuTypography);
181 }
182 
183 /*
184  * @tc.number: SUB_GRAPHIC_GRAPHIC_2D_SetTextUndefinedGlyphDisplay_004
185  * @tc.name  : OHDrawingSetTextUndefinedGlyphDisplay004
186  * @tc.desc  : Test undefined glyph display use only no glyph
187  * @tc.size  : MediumTest
188  * @tc.type  : Function
189  * @tc.level : Level 0
190  */
191 HWTEST_F(NativeUndefinedGlyphDisplayTest, OHDrawingSetTextUndefinedGlyphDisplay004, Function | MediumTest | Level0)
192 {
193     OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_DEFAULT);
194     OH_Drawing_SetTextUndefinedGlyphDisplay(static_cast<OH_Drawing_TextUndefinedGlyphDisplay>(NUM_100));
195     OH_Drawing_Typography* defaultTypography = PrepareCreateTypography(noGlyphText_);
196     EXPECT_NE(defaultTypography, nullptr);
197     BoundsResult(defaultTypography, noGlyphDefaultResult_, NUM_1);
198     OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_TOFU);
199     OH_Drawing_SetTextUndefinedGlyphDisplay(static_cast<OH_Drawing_TextUndefinedGlyphDisplay>(NUM_100));
200     OH_Drawing_Typography* tofuTypography = PrepareCreateTypography(noGlyphText_);
201     EXPECT_NE(tofuTypography, nullptr);
202     if (ExistNotdef()) {
203         BoundsResult(tofuTypography, noGlyphTofuResult_, NUM_1);
204     } else {
205         BoundsResult(defaultTypography, noGlyphDefaultResult_, NUM_1);
206     }
207     OH_Drawing_DestroyTypography(defaultTypography);
208     OH_Drawing_DestroyTypography(tofuTypography);
209 }
210 
211 /*
212  * @tc.number: SUB_GRAPHIC_GRAPHIC_2D_SetTextUndefinedGlyphDisplay_005
213  * @tc.name  : OHDrawingSetTextUndefinedGlyphDisplay005
214  * @tc.desc  : Test set family name, but still force tofu
215  * @tc.size  : MediumTest
216  * @tc.type  : Function
217  * @tc.level : Level 0
218  */
219 HWTEST_F(NativeUndefinedGlyphDisplayTest, OHDrawingSetTextUndefinedGlyphDisplay005, Function | MediumTest | Level0)
220 {
221     OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_TOFU);
222     const char* fontFamilies[] = { "Noto Sans" };
223     OH_Drawing_Typography* typography = PrepareCreateTypography(text_, fontFamilies, NUM_1);
224     EXPECT_NE(typography, nullptr);
225     if (ExistNotoSans()) {
226         BoundsResult(typography, notoResult_, NUM_3);
227     } else {
228         BoundsResult(typography, defaultResult_, NUM_3);
229     }
230     OH_Drawing_Typography* onlyTypography = PrepareCreateTypography(noGlyphText_, fontFamilies, NUM_1);
231     EXPECT_NE(onlyTypography, nullptr);
232     if (ExistNotdef()) {
233         BoundsResult(onlyTypography, noGlyphTofuResult_, NUM_1);
234     } else {
235         BoundsResult(onlyTypography, noGlyphDefaultResult_, NUM_1);
236     }
237     OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_DEFAULT);
238     OH_Drawing_DestroyTypography(typography);
239     OH_Drawing_DestroyTypography(onlyTypography);
240 }
241 }
242 } // namespace OHOS