• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "movingphoto_layout_algorithm.h"
17 #include "movingphoto_pattern.h"
18 
19 namespace OHOS::Ace::NG {
20 namespace {
21 constexpr int32_t ROUND_XMAGE_MODE_VALUE = 0;
22 constexpr int32_t ROUND_XMAGE_PIXEL_GAP = 2;
23 }
24 
Layout(LayoutWrapper * layoutWrapper)25 void MovingPhotoLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
26 {
27     BoxLayoutAlgorithm::PerformLayout(layoutWrapper);
28     auto contentOffset = layoutWrapper->GetGeometryNode()->GetContentOffset();
29     auto host = layoutWrapper->GetHostNode();
30     CHECK_NULL_VOID(host);
31     auto pattern = DynamicCast<MovingPhotoPattern>(host->GetPattern());
32     CHECK_NULL_VOID(pattern);
33     SizeF xmageOffset = GetXmageLayoutOffset(layoutWrapper);
34     for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) {
35         CHECK_NULL_VOID(child);
36         if (child->GetHostTag() == V2::IMAGE_ETS_TAG) {
37             child->GetGeometryNode()->SetMarginFrameOffset({ contentOffset.GetX(), contentOffset.GetY() });
38         } else if (child->GetHostTag() == V2::COLUMN_ETS_TAG) {
39             child->GetGeometryNode()->SetMarginFrameOffset(
40                 { contentOffset.GetX() + xmageOffset.Width(), contentOffset.GetY() + xmageOffset.Height() });
41         }
42         child->Layout();
43         if (child->GetHostTag() != V2::COLUMN_ETS_TAG) {
44             continue;
45         }
46         int32_t childCount = host->GetTotalChildCount();
47         CHECK_NULL_VOID(childCount >= 1);
48         auto childLayoutWrapper = host->GetChildByIndex(childCount - 1);
49         for (auto&& videoChild : childLayoutWrapper->GetAllChildrenWithBuild()) {
50             if (videoChild->GetHostTag() == V2::COLUMN_ETS_TAG) {
51                 videoChild->GetGeometryNode()->SetMarginFrameOffset({ contentOffset.GetX(), contentOffset.GetY() });
52             }
53             videoChild->Layout();
54         }
55     }
56 }
57 
Measure(LayoutWrapper * layoutWrapper)58 void MovingPhotoLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
59 {
60     auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
61     auto contentSize = layoutWrapper->GetGeometryNode()->GetContentSize();
62     auto host = layoutWrapper->GetHostNode();
63     CHECK_NULL_VOID(host);
64     auto pattern = DynamicCast<MovingPhotoPattern>(host->GetPattern());
65     CHECK_NULL_VOID(pattern);
66     pattern->SetXmagePosition();
67     if (pattern->GetXmageModeStatus() && pattern->GetXmageModeValue() != ROUND_XMAGE_MODE_VALUE) {
68         MeasureInXmageMode(layoutWrapper);
69         return;
70     }
71     for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) {
72         CHECK_NULL_VOID(child);
73         if (child->GetHostTag() == V2::IMAGE_ETS_TAG) {
74             auto layoutConstraintForImage = layoutConstraint;
75             layoutConstraintForImage.UpdateSelfMarginSizeWithCheck(OptionalSizeF(contentSize));
76             layoutConstraintForImage.UpdateMaxSizeWithCheck(contentSize);
77             layoutConstraintForImage.UpdateMinSizeWithCheck(contentSize);
78             child->Measure(layoutConstraintForImage);
79         } else if (child->GetHostTag() == V2::COLUMN_ETS_TAG) {
80             auto layoutConstraintForColumn = layoutConstraint;
81             layoutConstraintForColumn.UpdateSelfMarginSizeWithCheck(OptionalSizeF(contentSize));
82             layoutConstraintForColumn.UpdateMaxSizeWithCheck(contentSize);
83             layoutConstraintForColumn.UpdateMinSizeWithCheck(contentSize);
84             child->Measure(layoutConstraintForColumn);
85             int32_t childCount = host->GetTotalChildCount();
86             CHECK_NULL_VOID(childCount >= 1);
87             auto childLayoutWrapper = host->GetChildByIndex(childCount - 1);
88             ChildMeasure(childLayoutWrapper, contentSize, layoutConstraint);
89             if (childLayoutWrapper) {
90                 PerformMeasureSelf(&*childLayoutWrapper);
91             }
92         }
93     }
94     PerformMeasureSelf(layoutWrapper);
95 }
96 
ChildMeasure(RefPtr<LayoutWrapper> childLayoutWrapper,SizeF contentSize,LayoutConstraintF layoutConstraint)97 void MovingPhotoLayoutAlgorithm::ChildMeasure(RefPtr<LayoutWrapper> childLayoutWrapper,
98                                               SizeF contentSize, LayoutConstraintF layoutConstraint)
99 {
100     for (auto&& columnChild : childLayoutWrapper->GetAllChildrenWithBuild()) {
101         if (columnChild->GetHostTag() == V2::COLUMN_ETS_TAG) {
102             auto layoutConstraintForVideo = layoutConstraint;
103             layoutConstraintForVideo.UpdateSelfMarginSizeWithCheck(OptionalSizeF(contentSize));
104             layoutConstraintForVideo.UpdateMaxSizeWithCheck(contentSize);
105             layoutConstraintForVideo.UpdateMinSizeWithCheck(contentSize);
106             columnChild->Measure(layoutConstraintForVideo);
107         }
108     }
109 }
110 
111 
MeasureInXmageMode(LayoutWrapper * layoutWrapper)112 void MovingPhotoLayoutAlgorithm::MeasureInXmageMode(LayoutWrapper* layoutWrapper)
113 {
114     auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
115     auto contentSize = layoutWrapper->GetGeometryNode()->GetContentSize();
116     auto layoutProperty = DynamicCast<MovingPhotoLayoutProperty>(layoutWrapper->GetLayoutProperty());
117     CHECK_NULL_VOID(layoutProperty);
118     auto host = layoutWrapper->GetHostNode();
119     CHECK_NULL_VOID(host);
120     auto pattern = DynamicCast<MovingPhotoPattern>(host->GetPattern());
121     CHECK_NULL_VOID(pattern);
122     for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) {
123         CHECK_NULL_VOID(child);
124         if (child->GetHostTag() == V2::IMAGE_ETS_TAG) {
125             auto layoutConstraintForImage = layoutConstraint;
126             layoutConstraintForImage.UpdateSelfMarginSizeWithCheck(OptionalSizeF(contentSize));
127             layoutConstraintForImage.UpdateMaxSizeWithCheck(contentSize);
128             layoutConstraintForImage.UpdateMinSizeWithCheck(contentSize);
129             child->Measure(layoutConstraintForImage);
130         } else if (child->GetHostTag() == V2::COLUMN_ETS_TAG) {
131             auto layoutConstraintForColumn = layoutConstraint;
132             auto columnSize = contentSize;
133             SizeF xmageOffsetRatio = pattern->CalculateXmageOffsetRatio(contentSize);
134             SizeF imageSize = layoutProperty->GetImageSize().value();
135             columnSize.SetHeight(imageSize.Height() * xmageOffsetRatio.Height() + ROUND_XMAGE_PIXEL_GAP);
136             columnSize.SetWidth(imageSize.Width() * xmageOffsetRatio.Width() + ROUND_XMAGE_PIXEL_GAP);
137             layoutConstraintForColumn.UpdateSelfMarginSizeWithCheck(OptionalSizeF(columnSize));
138             layoutConstraintForColumn.UpdateMaxSizeWithCheck(columnSize);
139             layoutConstraintForColumn.UpdateMinSizeWithCheck(columnSize);
140             child->Measure(layoutConstraintForColumn);
141             int32_t childCount = host->GetTotalChildCount();
142             CHECK_NULL_VOID(childCount >= 1);
143             auto childLayoutWrapper = host->GetChildByIndex(childCount - 1);
144             ChildMeasureInXmage(childLayoutWrapper, contentSize, imageSize, xmageOffsetRatio, layoutConstraint);
145             if (childLayoutWrapper) {
146                 PerformMeasureSelf(&*childLayoutWrapper);
147             }
148         }
149     }
150     PerformMeasureSelf(layoutWrapper);
151 }
152 
ChildMeasureInXmage(RefPtr<LayoutWrapper> childLayoutWrapper,SizeF contentSize,SizeF imageSize,SizeF xmageRatio,LayoutConstraintF layoutConstraint)153 void MovingPhotoLayoutAlgorithm::ChildMeasureInXmage(RefPtr<LayoutWrapper> childLayoutWrapper, SizeF contentSize,
154     SizeF imageSize, SizeF xmageRatio, LayoutConstraintF layoutConstraint)
155 {
156     for (auto&& columnChild : childLayoutWrapper->GetAllChildrenWithBuild()) {
157         CHECK_NULL_VOID(columnChild);
158         if (columnChild->GetHostTag() == V2::COLUMN_ETS_TAG) {
159             auto layoutConstraintForVideo = layoutConstraint;
160             auto videoSize = contentSize;
161             videoSize.SetHeight(imageSize.Height() * xmageRatio.Height() + ROUND_XMAGE_PIXEL_GAP);
162             videoSize.SetWidth(imageSize.Width() * xmageRatio.Width() + ROUND_XMAGE_PIXEL_GAP);
163             layoutConstraintForVideo.UpdateSelfMarginSizeWithCheck(OptionalSizeF(videoSize));
164             layoutConstraintForVideo.UpdateMaxSizeWithCheck(videoSize);
165             layoutConstraintForVideo.UpdateMinSizeWithCheck(videoSize);
166             columnChild->Measure(layoutConstraintForVideo);
167         }
168     }
169 }
170 
MeasureContent(const LayoutConstraintF & contentConstraint,LayoutWrapper * layoutWrapper)171 std::optional<SizeF> MovingPhotoLayoutAlgorithm::MeasureContent(
172     const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
173 {
174     auto layoutSize = contentConstraint.selfIdealSize.IsValid() ? contentConstraint.selfIdealSize.ConvertToSizeT()
175                                                                 : contentConstraint.maxSize;
176     return layoutSize;
177 }
178 
GetXmageLayoutOffset(LayoutWrapper * layoutWrapper)179 SizeF MovingPhotoLayoutAlgorithm::GetXmageLayoutOffset(LayoutWrapper* layoutWrapper)
180 {
181     SizeF ret = SizeF(0, 0);
182     auto host = layoutWrapper->GetHostNode();
183     CHECK_NULL_RETURN(host, ret);
184     auto pattern = DynamicCast<MovingPhotoPattern>(host->GetPattern());
185     CHECK_NULL_RETURN(pattern, ret);
186     if (pattern->GetXmageModeStatus() && (pattern->GetXmageModeValue() == ROUND_XMAGE_MODE_VALUE)) {
187         auto contentSize = layoutWrapper->GetGeometryNode()->GetContentSize();
188         auto layoutProperty = DynamicCast<MovingPhotoLayoutProperty>(layoutWrapper->GetLayoutProperty());
189         CHECK_NULL_RETURN(layoutProperty, ret);
190         if (!layoutProperty->HasXmageOffset()) {
191             return ret;
192         }
193         SizeF xmageOffset = layoutProperty->GetXmageOffset().value();
194         SizeF xmageOffsetRatio = pattern->CalculateXmageOffsetRatio(contentSize);
195         ret = SizeF(xmageOffset.Width() * xmageOffsetRatio.Width() - 1,
196                     xmageOffset.Height() * xmageOffsetRatio.Height() - 1);
197     }
198     return ret;
199 }
200 } // namespace OHOS::Ace::NG