1 /*
2 * Copyright (c) 2021-2021 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 "ui_test_clip.h"
17
18 #include <cmath>
19 #include "common/image.h"
20 #include "draw/clip_utils.h"
21 #include "gfx_utils/graphic_math.h"
22 #include "securec.h"
23 #include "test_resource_config.h"
24
25 namespace OHOS {
26 namespace {
27 static float g_radius1 = 40.f;
28 static int16_t g_startAngle = 0;
29 static int16_t g_endAngle = 50;
30 }
SetUp()31 void UITestClip::SetUp()
32 {
33 if (container_ == nullptr) {
34 container_ = new UIScrollView();
35 container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT);
36 container_->SetHorizontalScrollState(false);
37 container_->SetThrowDrag(true);
38 }
39 positionY_ = 0;
40 }
41
TearDown()42 void UITestClip::TearDown()
43 {
44 DeleteChildren(container_);
45 container_ = nullptr;
46 }
47
GetTestView()48 UIView* UITestClip::GetTestView()
49 {
50 UIKitClipTest001();
51 UIKitClipTest002();
52 UIKitClipTest003();
53 UIKitClipTest004();
54 UIKitClipTest005();
55
56 return container_;
57 }
58
OnClick(UIView & view,const ClickEvent & event)59 bool UITestClip::OnClick(UIView& view, const ClickEvent& event)
60 {
61 bool caseChange1 = false;
62 bool caseChange2 = false;
63 if (&view == btnRadiusInc1_) {
64 g_radius1 += RADIUS_STEP_1;
65 caseChange1 = true;
66 } else if (&view == btnRadiusInc5_) {
67 g_radius1 += RADIUS_STEP_5;
68 caseChange1 = true;
69 } else if (&view == btnRadiusDec1_) {
70 g_radius1 -= RADIUS_STEP_1;
71 caseChange1 = true;
72 } else if (&view == btnRadiusDec5_) {
73 g_radius1 -= RADIUS_STEP_5;
74 caseChange1 = true;
75 } else if (&view == btnStartAngleInc_) {
76 g_startAngle += ANGLE_STEP;
77 caseChange2 = true;
78 } else if (&view == btnStartAngleDec_) {
79 g_startAngle -= ANGLE_STEP;
80 caseChange2 = true;
81 } else if (&view == btnEndAngleInc_) {
82 g_endAngle += ANGLE_STEP;
83 caseChange2 = true;
84 } else if (&view == btnEndAngleDec_) {
85 g_endAngle -= ANGLE_STEP;
86 caseChange2 = true;
87 }
88 if (caseChange1) {
89 char buffer[BUFFER_SIZE];
90 if (sprintf_s(buffer, BUFFER_SIZE, "当前半径 = %.0f", g_radius1) < 0) {
91 return false;
92 }
93 radiusText_->SetText(buffer);
94 ClipPath path;
95 // {70, 50}: center of circle
96 path.Circle({70, 50}, g_radius1);
97 imageView1_->SetSrc(JPEG_IMAGE_PATH);
98 ClipImage(imageView1_, path);
99 imageView1_->Invalidate();
100 }
101 if (caseChange2) {
102 ClipPath path;
103 // {80, 80}: center; 50: radius
104 path.MoveTo({80, 80}).Arc({80, 80}, 50, g_startAngle, g_endAngle);
105 imageView2_->SetSrc(JPEG_IMAGE_PATH);
106 ClipImage(imageView2_, path);
107 imageView2_->Invalidate();
108 }
109
110 return true;
111 }
112
CreateTitleLabel(const char * title)113 void UITestClip::CreateTitleLabel(const char* title)
114 {
115 UILabel* titleLabel = new UILabel();
116 titleLabel->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, Screen::GetInstance().GetWidth(), TITLE_HEIGHT);
117 titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
118 titleLabel->SetText(title);
119 container_->Add(titleLabel);
120 positionY_ += TITLE_HEIGHT + 8; // 8: gap
121 }
122
CreateImageView()123 UIImageView* UITestClip::CreateImageView()
124 {
125 UIViewGroup* viewGroup = new UIViewGroup();
126 viewGroup->SetHeight(BLOCK_HEIGHT);
127 viewGroup->SetWidth(BLOCK_WIDTH);
128 viewGroup->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, positionY_);
129 viewGroup->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
130 container_->Add(viewGroup);
131 positionY_ += BLOCK_HEIGHT + GAP;
132
133 UIImageView* imageVIew = new UIImageView();
134 imageVIew->SetPosition(IMAGE_POSITION_X, IMAGE_POSITION_Y);
135 imageVIew->SetSrc(JPEG_IMAGE_PATH);
136 viewGroup->Add(imageVIew);
137 return imageVIew;
138 }
139
SetUpButton(UILabelButton * btn,const char * title,int16_t x,int16_t y)140 void UITestClip::SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y)
141 {
142 if (btn == nullptr) {
143 return;
144 }
145 container_->Add(btn);
146 btn->SetPosition(x, y, BUTTON_WIDHT2, BUTTON_HEIGHT2);
147 btn->SetText(title);
148 btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE);
149 btn->SetOnClickListener(this);
150 btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED);
151 btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED);
152 btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE);
153 btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED);
154 btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED);
155 btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE);
156 }
157
ClipImage(UIImageView * imageView,ClipPath & path)158 void UITestClip::ClipImage(UIImageView* imageView, ClipPath& path)
159 {
160 const ImageInfo* info = imageView->GetImageInfo();
161 ClipImageBlitter blitter(info);
162 ClipUtils clip;
163 clip.PerformScan(path, blitter);
164 }
165
UIKitClipTest001()166 void UITestClip::UIKitClipTest001()
167 {
168 if (container_ == nullptr) {
169 return;
170 }
171 CreateTitleLabel("圆形裁剪 ");
172 int16_t x = VIEW_DISTANCE_TO_LEFT_SIDE + BLOCK_WIDTH + GAP;
173 int16_t y = positionY_;
174 btnRadiusInc1_ = new UILabelButton();
175 SetUpButton(btnRadiusInc1_, "半径+1", x, y);
176 btnRadiusDec1_ = new UILabelButton();
177 SetUpButton(btnRadiusDec1_, "半径-1", x + BUTTON_WIDHT2 + GAP, y);
178 btnRadiusInc5_ = new UILabelButton();
179 y += BUTTON_HEIGHT2 + GAP;
180 SetUpButton(btnRadiusInc5_, "半径+5", x, y);
181 btnRadiusDec5_ = new UILabelButton();
182 SetUpButton(btnRadiusDec5_, "半径-5", x + BUTTON_WIDHT2 + GAP, y);
183 y += BUTTON_HEIGHT2 + GAP;
184
185 radiusText_ = new UILabel();
186 radiusText_->SetPosition(x, y, Screen::GetInstance().GetWidth(), TITLE_HEIGHT);
187 radiusText_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
188 char buffer[BUFFER_SIZE];
189 if (sprintf_s(buffer, BUFFER_SIZE, "当前半径 = %.0f", g_radius1) >= 0) {
190 radiusText_->SetText(buffer);
191 }
192 container_->Add(radiusText_);
193
194 ClipPath path;
195 // {70, 50}: center of circle
196 path.Circle({70, 50}, g_radius1);
197
198 imageView1_ = CreateImageView();
199 ClipImage(imageView1_, path);
200 }
201
UIKitClipTest002()202 void UITestClip::UIKitClipTest002()
203 {
204 if (container_ == nullptr) {
205 return;
206 }
207 CreateTitleLabel("弧形裁剪 ");
208 int16_t x = VIEW_DISTANCE_TO_LEFT_SIDE + BLOCK_WIDTH + GAP;
209 int16_t y = positionY_;
210 btnStartAngleInc_ = new UILabelButton();
211 SetUpButton(btnStartAngleInc_, "起始角度+", x, y);
212 btnStartAngleDec_ = new UILabelButton();
213 SetUpButton(btnStartAngleDec_, "起始角度-", x + BUTTON_WIDHT2 + GAP, y);
214 btnEndAngleInc_ = new UILabelButton();
215 y += BUTTON_HEIGHT2 + GAP;
216 SetUpButton(btnEndAngleInc_, "结束角度+", x, y);
217 btnEndAngleDec_ = new UILabelButton();
218 SetUpButton(btnEndAngleDec_, "结束角度-", x + BUTTON_WIDHT2 + GAP, y);
219 y += BUTTON_HEIGHT2 + GAP;
220
221 ClipPath path;
222 // {80, 80}: center; 50: radius
223 path.MoveTo({80, 80}).Arc({80, 80}, 50, g_startAngle, g_endAngle);
224
225 imageView2_ = CreateImageView();
226 ClipImage(imageView2_, path);
227 }
228
UIKitClipTest003()229 void UITestClip::UIKitClipTest003()
230 {
231 if (container_ == nullptr) {
232 return;
233 }
234 CreateTitleLabel("多边形裁剪----五角星 ");
235
236 int32_t rot = 0;
237 // 80: Radius of outer circle
238 int32_t outerR = 80;
239 // 40: Radius of inner circle
240 int32_t innerR = 40;
241 // 50: The x-coordinate of the starting point
242 int32_t x = 50;
243 // 50: The y-coordinate of the starting point
244 int32_t y = 50;
245 // 180.0: The angle corresponding to PI
246 float pi = 180.0;
247 ClipPath path;
248 // 5: Needs to calculate five vertices
249 for (int32_t i = 0; i < 5; i++) {
250 // 18: constant 72: constant;
251 path.LineTo({static_cast<float>(cos((18 + 72 * i - rot) / pi * UI_PI) * outerR + x),
252 static_cast<float>(-sin((18 + 72 * i - rot) / pi * UI_PI) * outerR + y)}); // 18: constant 72: constant;
253 // 54: constant 72: constant;
254 path.LineTo({static_cast<float>(cos((54 + 72 * i - rot) / pi * UI_PI) * innerR + x),
255 static_cast<float>(-sin((54 + 72 * i - rot) / pi * UI_PI) * innerR + y)}); // 54: constant 72: constant;
256 }
257
258 UIImageView* imageView = CreateImageView();
259 ClipImage(imageView, path);
260 }
261
UIKitClipTest004()262 void UITestClip::UIKitClipTest004()
263 {
264 if (container_ == nullptr) {
265 return;
266 }
267 CreateTitleLabel("贝塞尔曲线裁剪 ");
268
269 ClipPath path;
270 // {50, 50}, {100, 50}, {100, 100}, {50, 100}: path points; {60, 110}, {80, 10}: control points of curve
271 path.MoveTo({50, 50}).CurveTo({60, 110}, {80, 10}, {100, 50}).LineTo({100, 100}).LineTo({50, 100});
272
273 UIImageView* imageView = CreateImageView();
274 ClipImage(imageView, path);
275 }
276
UIKitClipTest005()277 void UITestClip::UIKitClipTest005()
278 {
279 if (container_ == nullptr) {
280 return;
281 }
282 CreateTitleLabel("多边形裁剪 ");
283
284 ClipPath path;
285 // {20, 70}, {50, 60}, {110, 80}, {110, 130}, {50, 100}, {20, 120}: path points
286 path.MoveTo({20, 70}).LineTo({50, 60}).LineTo({110, 80}).LineTo({110, 130}).LineTo({50, 100}).LineTo({20, 120});
287
288 UIImageView* imageView = CreateImageView();
289 ClipImage(imageView, path);
290 }
291 };