1 /*
2  * Copyright (c) 2020-2022 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 
20 #include "common/image.h"
21 #include "draw/clip_utils.h"
22 #include "gfx_utils/graphic_math.h"
23 #include "securec.h"
24 #include "test_resource_config.h"
25 
26 namespace OHOS {
27 namespace {
28 static float g_radius1 = 40.f;
29 static int16_t g_startAngle = 0;
30 static int16_t g_endAngle = 50;
31 }
SetUp()32 void UITestClip::SetUp()
33 {
34     if (container_ == nullptr) {
35         container_ = new UIScrollView();
36         container_->Resize(Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight() - BACK_BUTTON_HEIGHT);
37         container_->SetHorizontalScrollState(false);
38         container_->SetThrowDrag(true);
39     }
40     positionY_ = 0;
41 }
42 
TearDown()43 void UITestClip::TearDown()
44 {
45     DeleteChildren(container_);
46     container_ = nullptr;
47 }
48 
GetTestView()49 UIView* UITestClip::GetTestView()
50 {
51     UIKitClipTest001();
52     UIKitClipTest002();
53     UIKitClipTest003();
54     UIKitClipTest004();
55     UIKitClipTest005();
56 
57     return container_;
58 }
59 
OnClick(UIView & view,const ClickEvent & event)60 bool UITestClip::OnClick(UIView& view, const ClickEvent& event)
61 {
62     bool caseChange1 = false;
63     bool caseChange2 = false;
64     if (&view == btnRadiusInc1_) {
65         g_radius1 += RADIUS_STEP_1;
66         caseChange1 = true;
67     } else if (&view == btnRadiusInc5_) {
68         g_radius1 += RADIUS_STEP_5;
69         caseChange1 = true;
70     } else if (&view == btnRadiusDec1_) {
71         g_radius1 -= RADIUS_STEP_1;
72         caseChange1 = true;
73     } else if (&view == btnRadiusDec5_) {
74         g_radius1 -= RADIUS_STEP_5;
75         caseChange1 = true;
76     } else if (&view == btnStartAngleInc_) {
77         g_startAngle += ANGLE_STEP;
78         caseChange2 = true;
79     } else if (&view == btnStartAngleDec_) {
80         g_startAngle -= ANGLE_STEP;
81         caseChange2 = true;
82     } else if (&view == btnEndAngleInc_) {
83         g_endAngle += ANGLE_STEP;
84         caseChange2 = true;
85     } else if (&view == btnEndAngleDec_) {
86         g_endAngle -= ANGLE_STEP;
87         caseChange2 = true;
88     }
89     if (caseChange1) {
90         char buffer[BUFFER_SIZE];
91         if (sprintf_s(buffer, BUFFER_SIZE, "当前半径 = %.0f", g_radius1) < 0) {
92             return false;
93         }
94         radiusText_->SetText(buffer);
95         ClipPath path;
96         // {70, 50}: center of circle
97         path.Circle({70, 50}, g_radius1);
98         imageView1_->SetSrc(JPEG_IMAGE_PATH);
99         ClipImage(imageView1_, path);
100         imageView1_->Invalidate();
101     }
102     if (caseChange2) {
103         ClipPath path;
104         // {80, 80}: center; 50: radius
105         path.MoveTo({80, 80}).Arc({80, 80}, 50, g_startAngle, g_endAngle);
106         imageView2_->SetSrc(JPEG_IMAGE_PATH);
107         ClipImage(imageView2_, path);
108         imageView2_->Invalidate();
109     }
110 
111     return true;
112 }
113 
CreateTitleLabel(const char * title)114 void UITestClip::CreateTitleLabel(const char* title)
115 {
116     UILabel* titleLabel = new UILabel();
117     titleLabel->SetPosition(TEXT_DISTANCE_TO_LEFT_SIDE, positionY_, Screen::GetInstance().GetWidth(), TITLE_HEIGHT);
118     titleLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
119     titleLabel->SetText(title);
120     container_->Add(titleLabel);
121     positionY_ += TITLE_HEIGHT + 8; // 8: gap
122 }
123 
CreateImageView()124 UIImageView* UITestClip::CreateImageView()
125 {
126     UIViewGroup* viewGroup = new UIViewGroup();
127     viewGroup->SetHeight(BLOCK_HEIGHT);
128     viewGroup->SetWidth(BLOCK_WIDTH);
129     viewGroup->SetPosition(VIEW_DISTANCE_TO_LEFT_SIDE, positionY_);
130     viewGroup->SetStyle(STYLE_BACKGROUND_COLOR, Color::Gray().full);
131     container_->Add(viewGroup);
132     positionY_ += BLOCK_HEIGHT + GAP;
133 
134     UIImageView* imageVIew = new UIImageView();
135     imageVIew->SetPosition(IMAGE_POSITION_X, IMAGE_POSITION_Y);
136     imageVIew->SetSrc(JPEG_IMAGE_PATH);
137     viewGroup->Add(imageVIew);
138     return imageVIew;
139 }
140 
SetUpButton(UILabelButton * btn,const char * title,int16_t x,int16_t y,const char * id)141 void UITestClip::SetUpButton(UILabelButton* btn, const char* title, int16_t x, int16_t y, const char* id)
142 {
143     if (btn == nullptr) {
144         return;
145     }
146     container_->Add(btn);
147     btn->SetPosition(x, y, BUTTON_WIDHT2, BUTTON_HEIGHT2);
148     btn->SetText(title);
149     btn->SetFont(DEFAULT_VECTOR_FONT_FILENAME, BUTTON_LABEL_SIZE);
150     btn->SetOnClickListener(this);
151     btn->SetViewId(id);
152     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::RELEASED);
153     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::PRESSED);
154     btn->SetStyleForState(STYLE_BORDER_RADIUS, BUTTON_STYLE_BORDER_RADIUS_VALUE, UIButton::INACTIVE);
155     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::RELEASED);
156     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::PRESSED);
157     btn->SetStyleForState(STYLE_BACKGROUND_COLOR, BUTTON_STYLE_BACKGROUND_COLOR_VALUE, UIButton::INACTIVE);
158 }
159 
ClipImage(UIImageView * imageView,ClipPath & path)160 void UITestClip::ClipImage(UIImageView* imageView, ClipPath& path)
161 {
162     const ImageInfo* info = imageView->GetImageInfo();
163     ClipUtils clip;
164     clip.PerformScan(path, info);
165 }
166 
UIKitClipTest001()167 void UITestClip::UIKitClipTest001()
168 {
169     if (container_ == nullptr) {
170         return;
171     }
172     CreateTitleLabel("圆形裁剪 ");
173     int16_t x = VIEW_DISTANCE_TO_LEFT_SIDE + BLOCK_WIDTH + GAP;
174     int16_t y = positionY_;
175     btnRadiusInc1_ = new UILabelButton();
176     SetUpButton(btnRadiusInc1_, "半径+1", x, y, UI_TEST_RADIUS_1);
177     btnRadiusDec1_ = new UILabelButton();
178     SetUpButton(btnRadiusDec1_, "半径-1", x + BUTTON_WIDHT2 + GAP, y, UI_TEST_RADIUS_2);
179     btnRadiusInc5_ = new UILabelButton();
180     y += BUTTON_HEIGHT2 + GAP;
181     SetUpButton(btnRadiusInc5_, "半径+5", x, y, UI_TEST_RADIUS_3);
182     btnRadiusDec5_ = new UILabelButton();
183     SetUpButton(btnRadiusDec5_, "半径-5", x + BUTTON_WIDHT2 + GAP, y, UI_TEST_RADIUS_4);
184     y += BUTTON_HEIGHT2 + GAP;
185 
186     radiusText_ = new UILabel();
187     radiusText_->SetPosition(x, y, Screen::GetInstance().GetWidth(), TITLE_HEIGHT);
188     radiusText_->SetFont(DEFAULT_VECTOR_FONT_FILENAME, FONT_DEFAULT_SIZE);
189     char buffer[BUFFER_SIZE];
190     if (sprintf_s(buffer, BUFFER_SIZE, "当前半径 = %.0f", g_radius1) >= 0) {
191         radiusText_->SetText(buffer);
192     }
193     container_->Add(radiusText_);
194 
195     ClipPath path;
196     // {70, 50}: center of circle
197     path.Circle({70, 50}, g_radius1);
198 
199     imageView1_ = CreateImageView();
200     ClipImage(imageView1_, path);
201 }
202 
UIKitClipTest002()203 void UITestClip::UIKitClipTest002()
204 {
205     if (container_ == nullptr) {
206         return;
207     }
208     CreateTitleLabel("弧形裁剪 ");
209     int16_t x = VIEW_DISTANCE_TO_LEFT_SIDE + BLOCK_WIDTH + GAP;
210     int16_t y = positionY_;
211     btnStartAngleInc_ = new UILabelButton();
212     SetUpButton(btnStartAngleInc_, "起始角度+", x, y, UI_TEST_ARC_1);
213     btnStartAngleDec_ = new UILabelButton();
214     SetUpButton(btnStartAngleDec_, "起始角度-", x + BUTTON_WIDHT2 + GAP, y, UI_TEST_ARC_2);
215     btnEndAngleInc_ = new UILabelButton();
216     y += BUTTON_HEIGHT2 + GAP;
217     SetUpButton(btnEndAngleInc_, "结束角度+", x, y, UI_TEST_ARC_3);
218     btnEndAngleDec_ = new UILabelButton();
219     SetUpButton(btnEndAngleDec_, "结束角度-", x + BUTTON_WIDHT2 + GAP, y, UI_TEST_ARC_4);
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     path.MoveTo({50, 50}).CurveTo({60, 110}, {80, 10}, {100, 50}).LineTo({100, 100}).LineTo({50, 100});
271 
272     UIImageView* imageView = CreateImageView();
273     ClipImage(imageView, path);
274 }
275 
UIKitClipTest005()276 void UITestClip::UIKitClipTest005()
277 {
278     if (container_ == nullptr) {
279         return;
280     }
281     CreateTitleLabel("多边形裁剪 ");
282 
283     ClipPath path;
284     path.MoveTo({20, 70}).LineTo({50, 60}).LineTo({110, 80}).LineTo({110, 130}).LineTo({50, 100}).LineTo({20, 120});
285 
286     UIImageView* imageView = CreateImageView();
287     ClipImage(imageView, path);
288 }
289 };
290