• 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->SetClipRadius(Radius(value));
111     };
112     return map;
113 };
114 
GetFloatPropertyGetterMap()115 FloatPropertyAnimatable::GetterMap RenderClip::GetFloatPropertyGetterMap()
116 {
117     FloatPropertyAnimatable::GetterMap map;
118     auto weak = AceType::WeakClaim(this);
119     map[PropertyAnimatableType::PROPERTY_WIDTH] = [weak]() -> float {
120         auto clip = weak.Upgrade();
121         if (!clip) {
122             LOGE("get width failed. clip is null.");
123             return 0.0;
124         }
125         return clip->width_;
126     };
127     map[PropertyAnimatableType::PROPERTY_HEIGHT] = [weak]() -> float {
128         auto clip = weak.Upgrade();
129         if (!clip) {
130             LOGE("get height failed. clip is null.");
131             return 0.0;
132         }
133         return clip->height_;
134     };
135     map[PropertyAnimatableType::PROPERTY_OFFSET_X] = [weak]() -> float {
136         auto clip = weak.Upgrade();
137         if (!clip) {
138             LOGE("get offsetX failed. clip is null.");
139             return 0.0;
140         }
141         return clip->offsetX_;
142     };
143     map[PropertyAnimatableType::PROPERTY_OFFSET_Y] = [weak]() -> float {
144         auto clip = weak.Upgrade();
145         if (!clip) {
146             LOGE("get offsetY failed. clip is null.");
147             return 0.0;
148         }
149         return clip->offsetY_;
150     };
151 
152     map[PropertyAnimatableType::PROPERTY_BORDER_RADIUS] = [weak]() -> float {
153         auto clip = weak.Upgrade();
154         if (!clip) {
155             LOGE("get borer radius failed. clip is null.");
156             return 0.0f;
157         }
158         return clip->topLeftRadius_.GetX().Value();
159     };
160     return map;
161 };
162 
GetClipRect(const Offset & offset) const163 Rect RenderClip::GetClipRect(const Offset& offset) const
164 {
165     double clipWidth = 0.0;
166     if (!NearZero(width_)) {
167         clipWidth = width_;
168     } else {
169         clipWidth = GetTransitionPaintRect().Width();
170     }
171     double clipHeight = 0.0;
172     if (!NearZero(height_)) {
173         clipHeight = height_;
174     } else {
175         clipHeight = GetTransitionPaintRect().Height();
176     }
177     return Rect(offset.GetX() + offsetX_, offset.GetY() + offsetY_, clipWidth, clipHeight);
178 }
179 
UpdateBoxForShadowAnimation()180 void RenderClip::UpdateBoxForShadowAnimation()
181 {
182     if (!clipWithShadow_) {
183         return;
184     }
185 
186     // If clip is used for animation, then there will be existed display and transform.
187     auto renderTransform = AceType::DynamicCast<RenderTransform>(GetParent().Upgrade());
188     if (!renderTransform) {
189         return;
190     }
191     auto renderDisplay = AceType::DynamicCast<RenderDisplay>(renderTransform->GetParent().Upgrade());
192     if (!renderDisplay) {
193         return;
194     }
195     // There must be box for shadow animation.
196     auto renderBox = DynamicCast<RenderBox>(renderDisplay->GetParent().Upgrade());
197     if (renderBox) {
198         renderBox->SetPaintSize(GetLayoutSize() - Size(offsetX_, offsetY_));
199         renderBox->SetPosition(shadowBoxOffset_ + Offset(offsetX_, offsetY_));
200         renderBox->MarkNeedRender();
201         SetPosition(Offset(-offsetX_, -offsetY_));
202     }
203 }
204 
Dump()205 void RenderClip::Dump()
206 {
207     DumpLog::GetInstance().AddDesc(std::string("Clip HW: ").append(Size(width_, height_).ToString()));
208     DumpLog::GetInstance().AddDesc(std::string("Clip Offset: ").append(Offset(offsetX_, offsetY_).ToString()));
209 }
210 
211 } // namespace OHOS::Ace
212