• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "core/components/clip/render_clip.h"
17 
18 #include "base/log/dump_log.h"
19 #include "base/log/event_report.h"
20 #include "base/utils/utils.h"
21 #include "core/components/box/render_box.h"
22 #include "core/components/clip/clip_component.h"
23 #include "core/components/display/render_display.h"
24 #include "core/components/transform/render_transform.h"
25 
26 namespace OHOS::Ace {
27 
Update(const RefPtr<Component> & component)28 void RenderClip::Update(const RefPtr<Component>& component)
29 {
30     const RefPtr<ClipComponent> clip = AceType::DynamicCast<ClipComponent>(component);
31     if (!clip) {
32         return;
33     }
34     clipWithShadow_ = clip->IsClipWithShadow();
35     followChildSize_ = clip->IsFollowChild();
36     width_ = NormalizeToPx(clip->GetWidth());
37     height_ = NormalizeToPx(clip->GetHeight());
38     offsetX_ = NormalizeToPx(clip->GetOffsetX());
39     offsetY_ = NormalizeToPx(clip->GetOffsetY());
40 
41     topLeftRadius_ = clip->GetTopLeftRadius();
42     topRightRadius_ = clip->GetTopRightRadius();
43     bottomLeftRadius_ = clip->GetBottomLeftRadius();
44     bottomRightRadius_ = clip->GetBottomRightRadius();
45 
46     MarkNeedLayout();
47 }
48 
PerformLayout()49 void RenderClip::PerformLayout()
50 {
51     if (GetChildren().empty()) {
52         LOGE("RenderClip: no child found in RenderClip!");
53         EventReport::SendRenderException(RenderExcepType::CLIP_ERR);
54         return;
55     }
56     auto child = GetChildren().front();
57     child->Layout(GetLayoutParam());
58     child->SetPosition(Offset::Zero());
59     if (followChildSize_) {
60         SetLayoutSize(child->GetLayoutSize());
61     } else {
62         SetLayoutSize(GetLayoutParam().GetMaxSize());
63     }
64 }
65 
GetFloatPropertySetterMap()66 FloatPropertyAnimatable::SetterMap RenderClip::GetFloatPropertySetterMap()
67 {
68     FloatPropertyAnimatable::SetterMap map;
69     auto weak = AceType::WeakClaim(this);
70     map[PropertyAnimatableType::PROPERTY_WIDTH] = [weak](float value) {
71         auto clip = weak.Upgrade();
72         if (!clip) {
73             LOGE("set width failed. clip is null.");
74             return;
75         }
76         clip->SetWidth(value);
77     };
78     map[PropertyAnimatableType::PROPERTY_HEIGHT] = [weak](float value) {
79         auto clip = weak.Upgrade();
80         if (!clip) {
81             LOGE("set height failed. clip is null.");
82             return;
83         }
84         clip->SetHeight(value);
85     };
86     map[PropertyAnimatableType::PROPERTY_OFFSET_X] = [weak](float value) {
87         auto clip = weak.Upgrade();
88         if (!clip) {
89             LOGE("set offsetX failed. clip is null.");
90             return;
91         }
92         clip->SetOffsetX(value);
93         clip->UpdateBoxForShadowAnimation();
94     };
95     map[PropertyAnimatableType::PROPERTY_OFFSET_Y] = [weak](float value) {
96         auto clip = weak.Upgrade();
97         if (!clip) {
98             LOGE("set offsetY failed. clip is null.");
99             return;
100         }
101         clip->SetOffsetY(value);
102         clip->UpdateBoxForShadowAnimation();
103     };
104     map[PropertyAnimatableType::PROPERTY_BORDER_RADIUS] = [weak](float value) {
105         auto clip = weak.Upgrade();
106         if (!clip) {
107             LOGE("set border radius failed. clip is null.");
108             return;
109         }
110         clip->topLeftRadius_ = Radius(value);
111         clip->topRightRadius_ = Radius(value);
112         clip->bottomLeftRadius_ = Radius(value);
113         clip->bottomRightRadius_ = Radius(value);
114         clip->SetClipRadius(Radius(value));
115     };
116     return map;
117 };
118 
GetFloatPropertyGetterMap()119 FloatPropertyAnimatable::GetterMap RenderClip::GetFloatPropertyGetterMap()
120 {
121     FloatPropertyAnimatable::GetterMap map;
122     auto weak = AceType::WeakClaim(this);
123     map[PropertyAnimatableType::PROPERTY_WIDTH] = [weak]() -> float {
124         auto clip = weak.Upgrade();
125         if (!clip) {
126             LOGE("get width failed. clip is null.");
127             return 0.0;
128         }
129         return clip->width_;
130     };
131     map[PropertyAnimatableType::PROPERTY_HEIGHT] = [weak]() -> float {
132         auto clip = weak.Upgrade();
133         if (!clip) {
134             LOGE("get height failed. clip is null.");
135             return 0.0;
136         }
137         return clip->height_;
138     };
139     map[PropertyAnimatableType::PROPERTY_OFFSET_X] = [weak]() -> float {
140         auto clip = weak.Upgrade();
141         if (!clip) {
142             LOGE("get offsetX failed. clip is null.");
143             return 0.0;
144         }
145         return clip->offsetX_;
146     };
147     map[PropertyAnimatableType::PROPERTY_OFFSET_Y] = [weak]() -> float {
148         auto clip = weak.Upgrade();
149         if (!clip) {
150             LOGE("get offsetY failed. clip is null.");
151             return 0.0;
152         }
153         return clip->offsetY_;
154     };
155 
156     map[PropertyAnimatableType::PROPERTY_BORDER_RADIUS] = [weak]() -> float {
157         auto clip = weak.Upgrade();
158         if (!clip) {
159             LOGE("get borer radius failed. clip is null.");
160             return 0.0f;
161         }
162         return clip->topLeftRadius_.GetX().Value();
163     };
164     return map;
165 };
166 
GetClipRect(const Offset & offset) const167 Rect RenderClip::GetClipRect(const Offset& offset) const
168 {
169     double clipWidth = 0.0;
170     if (!NearZero(width_)) {
171         clipWidth = width_;
172     } else {
173         clipWidth = GetTransitionPaintRect().Width();
174     }
175     double clipHeight = 0.0;
176     if (!NearZero(height_)) {
177         clipHeight = height_;
178     } else {
179         clipHeight = GetTransitionPaintRect().Height();
180     }
181     return Rect(offset.GetX() + offsetX_, offset.GetY() + offsetY_, clipWidth, clipHeight);
182 }
183 
UpdateBoxForShadowAnimation()184 void RenderClip::UpdateBoxForShadowAnimation()
185 {
186     if (!clipWithShadow_) {
187         return;
188     }
189 
190     // If clip if used for animation, then there will be exist display and transform.
191     auto renderTransform = AceType::DynamicCast<RenderTransform>(GetParent().Upgrade());
192     if (!renderTransform) {
193         return;
194     }
195     auto renderDisplay = AceType::DynamicCast<RenderDisplay>(renderTransform->GetParent().Upgrade());
196     if (!renderDisplay) {
197         return;
198     }
199     // There must be box for shadow animation.
200     auto renderBox = DynamicCast<RenderBox>(renderDisplay->GetParent().Upgrade());
201     if (renderBox) {
202         renderBox->SetPaintSize(GetLayoutSize() - Size(offsetX_, offsetY_));
203         renderBox->SetPosition(shadowBoxOffset_ + Offset(offsetX_, offsetY_));
204         renderBox->MarkNeedRender();
205         SetPosition(Offset(-offsetX_, -offsetY_));
206     }
207 }
208 
Dump()209 void RenderClip::Dump()
210 {
211     DumpLog::GetInstance().AddDesc(std::string("Clip HW: ").append(Size(width_, height_).ToString()));
212     DumpLog::GetInstance().AddDesc(std::string("Clip Offset: ").append(Offset(offsetX_, offsetY_).ToString()));
213 }
214 
215 } // namespace OHOS::Ace
216