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 <gtest/gtest.h>
17
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 OHOS {
29 namespace Rosen {
30 class NdkUndefinedGlyphDisplayTest : public testing::Test {
31 public:
32 OH_Drawing_Typography* PrepareCreateTypography(
33 const std::string& text, const char** fontFamilies = nullptr, int fontCount = 0);
34 void BoundsResult(OH_Drawing_Typography* typography, const float rectResult[][4], size_t size);
35
36 private:
37 static constexpr const char* text_ = "Hello 测 World \uffff\n!@#$%^&*~(){\uffff\uffff}[]90 - = ,.\n\uffff"
38 "testlp\uffff试\uffff Drawing\uffff";
39 static constexpr const char* noGlyphText_ = "\uffff";
40 static constexpr float defaultResult_[][4] = { { 2.0, 2.0, 206.63979, 29.0 }, { 1.0, 5.0, 388.10962, 37.0 },
41 { 0, 8.0, 319.4397, 42.0 } };
42 static constexpr float tofuResult_[][4] = { { 2.0, 2.0, 228.63979, 29.0 }, { 1.0, 5.0, 388.10962, 37.0 },
43 { 8.0, 8.0, 341.4397, 42.0 } };
44 static constexpr float notoResult_[][4] = { { 2.0, 2.0, 232.20976, 29.0 }, { 2.0, 5.0, 388.43961, 33.0 },
45 { 8.0, 8.0, 347.76962, 42.0 } };
46 static constexpr float noGlyphTofuResult_[][4] = { { 8.0, 0, 22.0, 22.0 } };
47 static constexpr float noGlyphDefaultResult_[][4] = { { 0, 0, 0, 0 } };
48 static constexpr float noGlyphNotoResult_[][4] = { { 0, 0, 0, 0 } };
49 };
50
PrepareCreateTypography(const std::string & text,const char ** fontFamilies,int fontCount)51 OH_Drawing_Typography* NdkUndefinedGlyphDisplayTest::PrepareCreateTypography(
52 const std::string& text, const char** fontFamilies, int fontCount)
53 {
54 double maxWidth = 500.0;
55 OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle();
56 EXPECT_NE(typoStyle, nullptr);
57 OH_Drawing_TextStyle* txtStyle = OH_Drawing_CreateTextStyle();
58 EXPECT_NE(txtStyle, nullptr);
59 OH_Drawing_SetTextStyleFontFamilies(txtStyle, fontCount, fontFamilies);
60 OH_Drawing_FontCollection* fontCollection = OH_Drawing_GetFontCollectionGlobalInstance();
61 EXPECT_NE(fontCollection, nullptr);
62 OH_Drawing_TypographyCreate* handler = OH_Drawing_CreateTypographyHandler(typoStyle, fontCollection);
63 EXPECT_NE(handler, nullptr);
64 OH_Drawing_SetTextStyleColor(txtStyle, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0x00));
65 double fontSize = 30;
66 OH_Drawing_SetTextStyleFontSize(txtStyle, fontSize);
67 OH_Drawing_SetTextStyleFontWeight(txtStyle, FONT_WEIGHT_400);
68 OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle);
69 OH_Drawing_TypographyHandlerAddText(handler, text.c_str());
70 OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(handler);
71 EXPECT_NE(typography, nullptr);
72 OH_Drawing_TypographyLayout(typography, maxWidth);
73 OH_Drawing_DestroyTypographyStyle(typoStyle);
74 OH_Drawing_DestroyTextStyle(txtStyle);
75 OH_Drawing_DestroyTypographyHandler(handler);
76 return typography;
77 }
78
BoundsResult(OH_Drawing_Typography * typography,const float rectResult[][4],size_t size)79 void NdkUndefinedGlyphDisplayTest::BoundsResult(
80 OH_Drawing_Typography* typography, const float rectResult[][4], size_t size)
81 {
82 OH_Drawing_Array* textLines = OH_Drawing_TypographyGetTextLines(typography);
83 size_t arraySize = OH_Drawing_GetDrawingArraySize(textLines);
84 EXPECT_EQ(size, arraySize);
85 for (size_t index = 0; index < arraySize; index++) {
86 OH_Drawing_TextLine* textLine = OH_Drawing_GetTextLineByIndex(textLines, index);
87 OH_Drawing_Rect* rect = OH_Drawing_TextLineGetImageBounds(textLine);
88 EXPECT_FLOAT_EQ(rectResult[index][0], OH_Drawing_RectGetLeft(rect));
89 EXPECT_FLOAT_EQ(rectResult[index][1], OH_Drawing_RectGetTop(rect));
90 // 2 is the index of right
91 EXPECT_FLOAT_EQ(rectResult[index][2], OH_Drawing_RectGetRight(rect));
92 // 3 is the index of bottom
93 EXPECT_FLOAT_EQ(rectResult[index][3], OH_Drawing_RectGetBottom(rect));
94 OH_Drawing_RectDestroy(rect);
95 OH_Drawing_DestroyTextLine(textLine);
96 }
97 OH_Drawing_DestroyTextLines(textLines);
98 }
99
100 /**
101 * @tc.name: NdkUndefinedGlyphDisplayTest001
102 * @tc.desc: Test undefined glyph display use tofu
103 * @tc.type: FUNC
104 */
105 HWTEST_F(NdkUndefinedGlyphDisplayTest, NdkUndefinedGlyphDisplayTest001, TestSize.Level0)
106 {
107 OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_TOFU);
108 OH_Drawing_Typography* typography = PrepareCreateTypography(text_);
109 EXPECT_NE(typography, nullptr);
110 BoundsResult(typography, tofuResult_, 3);
111 OH_Drawing_DestroyTypography(typography);
112 }
113
114 /**
115 * @tc.name: NdkUndefinedGlyphDisplayTest002
116 * @tc.desc: Test undefined glyph display use default
117 * @tc.type: FUNC
118 */
119 HWTEST_F(NdkUndefinedGlyphDisplayTest, NdkUndefinedGlyphDisplayTest002, TestSize.Level0)
120 {
121 OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_DEFAULT);
122 OH_Drawing_Typography* typography = PrepareCreateTypography(text_);
123 EXPECT_NE(typography, nullptr);
124 BoundsResult(typography, defaultResult_, 3);
125 OH_Drawing_DestroyTypography(typography);
126 }
127
128 /**
129 * @tc.name: NdkUndefinedGlyphDisplayTest003
130 * @tc.desc: Test undefined glyph display use invalid input
131 * @tc.type: FUNC
132 */
133 HWTEST_F(NdkUndefinedGlyphDisplayTest, NdkUndefinedGlyphDisplayTest003, TestSize.Level0)
134 {
135 OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_DEFAULT);
136 OH_Drawing_SetTextUndefinedGlyphDisplay(static_cast<OH_Drawing_TextUndefinedGlyphDisplay>(100));
137 OH_Drawing_Typography* defaultTypography = PrepareCreateTypography(text_);
138 EXPECT_NE(defaultTypography, nullptr);
139 BoundsResult(defaultTypography, defaultResult_, 3);
140 OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_TOFU);
141 OH_Drawing_SetTextUndefinedGlyphDisplay(static_cast<OH_Drawing_TextUndefinedGlyphDisplay>(100));
142 OH_Drawing_Typography* tofuTypography = PrepareCreateTypography(text_);
143 EXPECT_NE(tofuTypography, nullptr);
144 BoundsResult(tofuTypography, tofuResult_, 3);
145 OH_Drawing_DestroyTypography(defaultTypography);
146 OH_Drawing_DestroyTypography(tofuTypography);
147 }
148
149 /**
150 * @tc.name: NdkUndefinedGlyphDisplayTest004
151 * @tc.desc: Test undefined glyph display use only no glyph
152 * @tc.type: FUNC
153 */
154 HWTEST_F(NdkUndefinedGlyphDisplayTest, NdkUndefinedGlyphDisplayTest004, TestSize.Level0)
155 {
156 OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_DEFAULT);
157 OH_Drawing_SetTextUndefinedGlyphDisplay(static_cast<OH_Drawing_TextUndefinedGlyphDisplay>(100));
158 OH_Drawing_Typography* defaultTypography = PrepareCreateTypography(noGlyphText_);
159 EXPECT_NE(defaultTypography, nullptr);
160 BoundsResult(defaultTypography, noGlyphDefaultResult_, 1);
161 OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_TOFU);
162 OH_Drawing_SetTextUndefinedGlyphDisplay(static_cast<OH_Drawing_TextUndefinedGlyphDisplay>(100));
163 OH_Drawing_Typography* tofuTypography = PrepareCreateTypography(noGlyphText_);
164 EXPECT_NE(tofuTypography, nullptr);
165 BoundsResult(tofuTypography, noGlyphTofuResult_, 1);
166 OH_Drawing_DestroyTypography(defaultTypography);
167 OH_Drawing_DestroyTypography(tofuTypography);
168 }
169
170 /**
171 * @tc.name: NdkUndefinedGlyphDisplayTest005
172 * @tc.desc: Test set family name, but still force tofu
173 * @tc.type: FUNC
174 */
175 HWTEST_F(NdkUndefinedGlyphDisplayTest, NdkUndefinedGlyphDisplayTest005, TestSize.Level0)
176 {
177 OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_TOFU);
178 const char* fontFamilies[] = { "Noto Sans" };
179 OH_Drawing_Typography* typography = PrepareCreateTypography(text_, fontFamilies, 1);
180 EXPECT_NE(typography, nullptr);
181 BoundsResult(typography, notoResult_, 3);
182 OH_Drawing_Typography* onlyTypography = PrepareCreateTypography(noGlyphText_, fontFamilies, 1);
183 EXPECT_NE(onlyTypography, nullptr);
184 BoundsResult(onlyTypography, noGlyphTofuResult_, 1);
185 OH_Drawing_SetTextUndefinedGlyphDisplay(TEXT_UNDEFINED_GLYPH_USE_DEFAULT);
186 OH_Drawing_DestroyTypography(typography);
187 OH_Drawing_DestroyTypography(onlyTypography);
188 }
189 } // namespace Rosen
190 } // namespace OHOS