1 /*
2 * Copyright (c) 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_ng/pattern/shape/shape_container_pattern.h"
17
18 #include <algorithm>
19
20 #include "base/geometry/ng/rect_t.h"
21 #include "base/utils/utils.h"
22
23 namespace OHOS::Ace::NG {
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,bool skipMeasure,bool skipLayout)24 bool ShapeContainerPattern::OnDirtyLayoutWrapperSwap(
25 const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout)
26 {
27 if (skipMeasure || dirty->SkipMeasureContent() || isShapeContainerInit_) {
28 return false;
29 }
30 ViewPortTransform();
31 return true;
32 }
33
ViewPortTransform()34 void ShapeContainerPattern::ViewPortTransform()
35 {
36 auto curFrameNode = GetHost();
37 auto renderContext = curFrameNode->GetRenderContext();
38 auto geoNode = curFrameNode->GetGeometryNode();
39 CHECK_NULL_VOID(geoNode);
40 auto contentSize = geoNode->GetContentSize();
41 auto paintProperty = curFrameNode->GetPaintProperty<ShapeContainerPaintProperty>();
42 if (paintProperty->HasShapeViewBox() && paintProperty->GetShapeViewBoxValue().IsValid()) {
43 double portWidth = paintProperty->GetShapeViewBoxValue().Width().ConvertToPx();
44 double portHeight = paintProperty->GetShapeViewBoxValue().Height().ConvertToPx();
45 double portLeft = paintProperty->GetShapeViewBoxValue().Left().ConvertToPx();
46 double portTop = paintProperty->GetShapeViewBoxValue().Top().ConvertToPx();
47 if (contentSize.IsPositive() && GreatNotEqual(portWidth, 0.0) && GreatNotEqual(portHeight, 0.0)) {
48 double scale = std::min(contentSize.Width() / portWidth, contentSize.Height() / portHeight);
49 double tx = contentSize.Width() * 0.5 - (portWidth * 0.5 + portLeft) * scale;
50 double ty = contentSize.Height() * 0.5 - (portHeight * 0.5 + portTop) * scale;
51 for (const auto& child : curFrameNode->GetChildren()) {
52 auto node = AceType::DynamicCast<FrameNode>(child);
53 CHECK_NULL_VOID(node);
54 auto context = node->GetRenderContext();
55 CHECK_NULL_VOID(context);
56 context->UpdateTransformCenter(DimensionOffset(Offset(0.0, 0.0)));
57 context->OnTransformTranslateUpdate({ tx, ty, 0 });
58 context->OnTransformScaleUpdate({ scale, scale });
59
60 if (context->HasOffset()) {
61 auto currentOffset = context->GetOffset();
62 auto newOffset = OffsetT(Dimension(currentOffset->GetX() * scale),
63 Dimension(currentOffset->GetY() * scale));
64 context->UpdateOffset(newOffset);
65 context->OnOffsetUpdate(newOffset);
66 node->MarkModifyDone();
67 }
68 }
69 }
70 }
71 isShapeContainerInit_ = true;
72 }
73
OnModifyDone()74 void ShapeContainerPattern::OnModifyDone()
75 {
76 auto host = GetHost();
77 CHECK_NULL_VOID(host);
78 auto paintProperty = host->GetPaintProperty<ShapeContainerPaintProperty>();
79 CHECK_NULL_VOID(paintProperty);
80 if (paintProperty->HasStrokeMiterLimit()) {
81 auto miterLimit = paintProperty->GetStrokeMiterLimitValue();
82 if (Negative(miterLimit)) {
83 paintProperty->UpdateStrokeMiterLimit(ShapePaintProperty::STROKE_MITERLIMIT_DEFAULT);
84 } else if (NonNegative(miterLimit) &&
85 LessNotEqual(miterLimit, ShapePaintProperty::STROKE_MITERLIMIT_MIN)) {
86 paintProperty->UpdateStrokeMiterLimit(ShapePaintProperty::STROKE_MITERLIMIT_MIN);
87 }
88 }
89
90 Pattern::OnModifyDone();
91 for (auto childNode : ChildNodes_) {
92 auto child = childNode.Upgrade();
93 if (!child) {
94 continue;
95 }
96 child->MarkNeedRenderOnly();
97 }
98 ChildNodes_.clear();
99 }
100
OnAttachToFrameNode()101 void ShapeContainerPattern::OnAttachToFrameNode()
102 {
103 auto host = GetHost();
104 CHECK_NULL_VOID(host);
105 host->GetLayoutProperty()->UpdateAlignment(Alignment::TOP_LEFT);
106 host->GetRenderContext()->SetClipToFrame(true);
107 }
108 } // namespace OHOS::Ace::NG
109