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/video/render_texture.h"
17
18 #include "core/components/theme/theme_manager.h"
19 #include "core/components/video/video_component.h"
20 #include "core/components/video/video_theme.h"
21
22 namespace OHOS::Ace {
23
RenderTexture()24 RenderTexture::RenderTexture() : RenderNode(true) {}
25
Update(const RefPtr<Component> & component)26 void RenderTexture::Update(const RefPtr<Component>& component)
27 {
28 const RefPtr<TextureComponent> texture = AceType::DynamicCast<TextureComponent>(component);
29 if (!texture) {
30 return;
31 }
32
33 textureId_ = texture->GetTextureId();
34 auto sourceSize = Size(static_cast<double>(texture->GetSrcWidth()), static_cast<double>(texture->GetSrcHeight()));
35 if (sourceSize.IsValid()) {
36 sourceSize_ = sourceSize;
37 }
38 #if (!defined OHOS_STANDARD_SYSTEM) || (defined ENABLE_ROSEN_BACKEND)
39 imageFit_ = texture->GetFit();
40 #endif
41 imagePosition_ = texture->GetImagePosition();
42 InitControlsHeight(component);
43
44 MarkNeedLayout();
45 }
46
InitControlsHeight(const RefPtr<Component> & component)47 void RenderTexture::InitControlsHeight(const RefPtr<Component>& component)
48 {
49 controlsHeight_ = 0.0;
50 auto context = context_.Upgrade();
51 if (!context) {
52 LOGE("context is null");
53 return;
54 }
55
56 auto themeManager = context->GetThemeManager();
57 if (!themeManager) {
58 LOGE("theme manager is null");
59 return;
60 }
61
62 auto videoTheme = themeManager->GetTheme<VideoTheme>();
63 if (!videoTheme) {
64 LOGE("video theme is null");
65 return;
66 }
67
68 auto videoComponent = AceType::DynamicCast<VideoComponent>(component);
69 if (!videoComponent) {
70 LOGI("component is not video");
71 return;
72 }
73
74 if (videoComponent->NeedControls()) {
75 controlsHeight_ += NormalizeToPx(Dimension(videoTheme->GetBtnSize().Height(), DimensionUnit::VP));
76 controlsHeight_ += NormalizeToPx(videoTheme->GetBtnEdge().Top());
77 controlsHeight_ += NormalizeToPx(videoTheme->GetBtnEdge().Bottom());
78 }
79 }
80
SetHidden(bool hidden,bool inRecursion)81 void RenderTexture::SetHidden(bool hidden, bool inRecursion)
82 {
83 RenderNode::SetHidden(hidden, inRecursion);
84 if (hiddenChangeEvent_) {
85 hiddenChangeEvent_(hidden);
86 }
87 }
88
PerformLayout()89 void RenderTexture::PerformLayout()
90 {
91 if (!NeedLayout()) {
92 return;
93 }
94 double width = GetLayoutParam().GetMinSize().Width();
95 double height = GetLayoutParam().GetMinSize().Height();
96 for (const auto& item : GetChildren()) {
97 item->Layout(GetLayoutParam());
98 width = std::max(width, item->GetLayoutSize().Width());
99 height = std::max(height, item->GetLayoutSize().Height());
100 }
101
102 if (!GetLayoutParam().GetMaxSize().IsInfinite()) {
103 SetLayoutSize(GetLayoutParam().GetMaxSize());
104 } else {
105 SetLayoutSize(Size(width, height));
106 }
107
108 switch (imageFit_) {
109 case ImageFit::CONTAIN:
110 CalculateFitContain();
111 break;
112 case ImageFit::FILL:
113 CalculateFitFill();
114 break;
115 case ImageFit::COVER:
116 CalculateFitCover();
117 break;
118 case ImageFit::NONE:
119 CalculateFitNone();
120 break;
121 case ImageFit::SCALEDOWN:
122 CalculateFitScaleDown();
123 break;
124 default:
125 CalculateFitContain();
126 break;
127 }
128
129 ApplyObjectPosition();
130
131 SetNeedLayout(false);
132 if (textureSizeChangeEvent_) {
133 textureSizeChangeEvent_(textureId_, drawSize_.Width(), drawSize_.Height());
134 }
135 if (textureOffsetChangeEvent_) {
136 textureOffsetChangeEvent_(textureId_,
137 (int32_t)(alignmentX_ + GetGlobalOffset().GetX()), (int32_t)(alignmentY_ + GetGlobalOffset().GetY()));
138 }
139 MarkNeedRender();
140 }
141
ApplyObjectPosition()142 void RenderTexture::ApplyObjectPosition()
143 {
144 const Size& layoutSize = GetLayoutSize();
145 if (imagePosition_.GetSizeTypeX() == BackgroundImagePositionType::PX) {
146 alignmentX_ = imagePosition_.GetSizeValueX();
147 } else {
148 alignmentX_ = imagePosition_.GetSizeValueX() * (layoutSize.Width() - drawSize_.Width()) / PERCENT_TRANSLATE;
149 }
150
151 if (imagePosition_.GetSizeTypeY() == BackgroundImagePositionType::PX) {
152 alignmentY_ = imagePosition_.GetSizeValueY();
153 } else {
154 alignmentY_ = imagePosition_.GetSizeValueY() * (layoutSize.Height() - drawSize_.Height()) / PERCENT_TRANSLATE;
155 }
156 }
157
CalculateFitContain()158 void RenderTexture::CalculateFitContain()
159 {
160 const Size& layoutSize = GetLayoutSize();
161 double layoutRatio = NearZero(layoutSize.Height()) ? 0.0 : layoutSize.Width() / layoutSize.Height();
162 double sourceRatio = NearZero(sourceSize_.Height()) ? layoutRatio : sourceSize_.Width() / sourceSize_.Height();
163
164 if (NearZero(layoutRatio) || NearZero(sourceRatio)) {
165 drawSize_ = layoutSize;
166 } else if (sourceRatio < layoutRatio) {
167 drawSize_ = Size(sourceRatio * layoutSize.Height(), layoutSize.Height());
168 } else {
169 drawSize_ = Size(layoutSize.Width(), layoutSize.Width() / sourceRatio);
170 }
171 }
172
CalculateFitCover()173 void RenderTexture::CalculateFitCover()
174 {
175 const Size& layoutSize = GetLayoutSize();
176 double layoutRatio = NearZero(layoutSize.Height()) ? 0.0 : layoutSize.Width() / layoutSize.Height();
177 double sourceRatio = NearZero(sourceSize_.Height()) ? layoutRatio : sourceSize_.Width() / sourceSize_.Height();
178
179 if (NearZero(layoutRatio) || NearZero(sourceRatio)) {
180 drawSize_ = layoutSize;
181 } else if (sourceRatio < layoutRatio) {
182 drawSize_ = Size(layoutSize.Width(), layoutSize.Width() / sourceRatio);
183 } else {
184 drawSize_ = Size(layoutSize.Height() * sourceRatio, layoutSize.Height());
185 }
186 }
187
CalculateFitFill()188 void RenderTexture::CalculateFitFill()
189 {
190 drawSize_ = GetLayoutSize();
191 }
192
CalculateFitNone()193 void RenderTexture::CalculateFitNone()
194 {
195 drawSize_ = sourceSize_;
196 }
197
CalculateFitScaleDown()198 void RenderTexture::CalculateFitScaleDown()
199 {
200 const Size& LayoutSize = GetLayoutSize();
201
202 if (LayoutSize.Width() > sourceSize_.Width()) {
203 CalculateFitNone();
204 } else {
205 CalculateFitContain();
206 }
207 }
208
209 } // namespace OHOS::Ace
210