1 /*
2 * Copyright (c) 2021-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 "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 imageFit_ = texture->GetFit();
39 imagePosition_ = texture->GetImagePosition();
40 InitControlsHeight(component);
41
42 MarkNeedLayout();
43 }
44
InitControlsHeight(const RefPtr<Component> & component)45 void RenderTexture::InitControlsHeight(const RefPtr<Component>& component)
46 {
47 controlsHeight_ = 0.0;
48 auto context = context_.Upgrade();
49 if (!context) {
50 LOGE("context is null");
51 return;
52 }
53
54 auto themeManager = context->GetThemeManager();
55 if (!themeManager) {
56 LOGE("theme manager is null");
57 return;
58 }
59
60 auto videoTheme = themeManager->GetTheme<VideoTheme>();
61 if (!videoTheme) {
62 LOGE("video theme is null");
63 return;
64 }
65
66 auto videoComponent = AceType::DynamicCast<VideoComponent>(component);
67 if (!videoComponent) {
68 LOGI("component is not video");
69 return;
70 }
71
72 if (videoComponent->NeedControls()) {
73 controlsHeight_ += NormalizeToPx(Dimension(videoTheme->GetBtnSize().Height(), DimensionUnit::VP));
74 controlsHeight_ += NormalizeToPx(videoTheme->GetBtnEdge().Top());
75 controlsHeight_ += NormalizeToPx(videoTheme->GetBtnEdge().Bottom());
76 }
77 }
78
SetHidden(bool hidden,bool inRecursion)79 void RenderTexture::SetHidden(bool hidden, bool inRecursion)
80 {
81 RenderNode::SetHidden(hidden, inRecursion);
82 if (hiddenChangeEvent_) {
83 hiddenChangeEvent_(hidden);
84 }
85 }
86
PerformLayout()87 void RenderTexture::PerformLayout()
88 {
89 if (!NeedLayout()) {
90 return;
91 }
92 Measure();
93 SetNeedLayout(false);
94 if (textureSizeChangeEvent_) {
95 textureSizeChangeEvent_(textureId_, drawSize_.Width(), drawSize_.Height());
96 }
97 if (textureOffsetChangeEvent_) {
98 textureOffsetChangeEvent_(textureId_,
99 (int32_t)(alignmentX_ + GetGlobalOffset().GetX()), (int32_t)(alignmentY_ + GetGlobalOffset().GetY()));
100 }
101 MarkNeedRender();
102 }
103
Measure()104 void RenderTexture::Measure()
105 {
106 double width = GetLayoutParam().GetMinSize().Width();
107 double height = GetLayoutParam().GetMinSize().Height();
108 for (const auto& item : GetChildren()) {
109 item->Layout(GetLayoutParam());
110 width = std::max(width, item->GetLayoutSize().Width());
111 height = std::max(height, item->GetLayoutSize().Height());
112 }
113
114 if (!GetLayoutParam().GetMaxSize().IsInfinite()) {
115 SetLayoutSize(GetLayoutParam().GetMaxSize());
116 } else {
117 SetLayoutSize(Size(width, height));
118 }
119
120 switch (imageFit_) {
121 case ImageFit::CONTAIN:
122 CalculateFitContain();
123 break;
124 case ImageFit::FILL:
125 CalculateFitFill();
126 break;
127 case ImageFit::COVER:
128 CalculateFitCover();
129 break;
130 case ImageFit::NONE:
131 CalculateFitNone();
132 break;
133 case ImageFit::SCALE_DOWN:
134 CalculateFitScaleDown();
135 break;
136 default:
137 CalculateFitContain();
138 break;
139 }
140
141 ApplyObjectPosition();
142 }
143
ApplyObjectPosition()144 void RenderTexture::ApplyObjectPosition()
145 {
146 const Size& layoutSize = GetLayoutSize();
147 if (imagePosition_.GetSizeTypeX() == BackgroundImagePositionType::PX) {
148 alignmentX_ = imagePosition_.GetSizeValueX();
149 } else {
150 alignmentX_ = imagePosition_.GetSizeValueX() * (layoutSize.Width() - drawSize_.Width()) / PERCENT_TRANSLATE;
151 }
152
153 if (imagePosition_.GetSizeTypeY() == BackgroundImagePositionType::PX) {
154 alignmentY_ = imagePosition_.GetSizeValueY();
155 } else {
156 alignmentY_ = imagePosition_.GetSizeValueY() * (layoutSize.Height() - drawSize_.Height()) / PERCENT_TRANSLATE;
157 }
158 }
159
CalculateFitContain()160 void RenderTexture::CalculateFitContain()
161 {
162 const Size& layoutSize = GetLayoutSize();
163 double layoutRatio = NearZero(layoutSize.Height()) ? 0.0 : layoutSize.Width() / layoutSize.Height();
164 double sourceRatio = NearZero(sourceSize_.Height()) ? layoutRatio : sourceSize_.Width() / sourceSize_.Height();
165 if (NearZero(layoutRatio) || NearZero(sourceRatio)) {
166 drawSize_ = layoutSize;
167 } else if (sourceRatio < layoutRatio) {
168 drawSize_ = Size(sourceRatio * layoutSize.Height(), layoutSize.Height());
169 } else {
170 drawSize_ = Size(layoutSize.Width(), layoutSize.Width() / sourceRatio);
171 }
172 }
173
CalculateFitCover()174 void RenderTexture::CalculateFitCover()
175 {
176 const Size& layoutSize = GetLayoutSize();
177 double layoutRatio = NearZero(layoutSize.Height()) ? 0.0 : layoutSize.Width() / layoutSize.Height();
178 double sourceRatio = NearZero(sourceSize_.Height()) ? layoutRatio : sourceSize_.Width() / sourceSize_.Height();
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