• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "core/components_ng/pattern/security_component/security_component_layout_element.h"
16 
17 #include "base/log/ace_scoring_log.h"
18 #include "base/memory/ace_type.h"
19 #include "core/components_ng/pattern/image/image_layout_property.h"
20 #include "core/components_ng/pattern/security_component/security_component_layout_property.h"
21 #include "core/components_ng/pattern/security_component/security_component_theme.h"
22 #include "core/components_ng/pattern/text/text_layout_property.h"
23 #include "core/components_ng/property/measure_property.h"
24 #include "core/pipeline_ng/pipeline_context.h"
25 #ifdef ENABLE_ROSEN_BACKEND
26 #include "core/components/custom_paint/rosen_render_custom_paint.h"
27 #endif
28 
29 namespace OHOS::Ace::NG {
Init(RefPtr<SecurityComponentLayoutProperty> & property,RefPtr<LayoutWrapper> & iconWrap)30 void IconLayoutElement::Init(RefPtr<SecurityComponentLayoutProperty>& property,
31     RefPtr<LayoutWrapper>& iconWrap)
32 {
33     secCompProperty_ = property;
34     iconWrap_ = iconWrap;
35     CHECK_NULL_VOID(property);
36     CHECK_NULL_VOID(iconWrap);
37     if (property->GetIconStyle().value_or(-1) ==
38         static_cast<int32_t>(SecurityComponentIconStyle::ICON_NULL)) {
39         return;
40     }
41     isExist_ = true;
42 
43     auto pipeline = PipelineContext::GetCurrentContext();
44     CHECK_NULL_VOID(pipeline);
45     auto theme = pipeline->GetTheme<SecurityComponentTheme>();
46     CHECK_NULL_VOID(theme);
47     minIconSize_ = theme->GetMinIconSize().ConvertToPx();
48 
49     if (property->GetIconSize().has_value()) {
50         isSetSize_ = true;
51         width_ = height_ = property->GetIconSize().value().ConvertToPx();
52     } else {
53         width_ = height_ = theme->GetIconSize().ConvertToPx();
54     }
55 }
56 
DoMeasure()57 void IconLayoutElement::DoMeasure()
58 {
59     if (!isExist_) {
60         return;
61     }
62     auto iconConstraint = secCompProperty_->CreateChildConstraint();
63     iconConstraint.selfIdealSize.SetWidth(width_);
64     iconConstraint.selfIdealSize.SetHeight(height_);
65     iconWrap_->Measure(iconConstraint);
66 }
67 
ShrinkWidth(double reduceSize)68 double IconLayoutElement::ShrinkWidth(double reduceSize)
69 {
70     if (!isExist_ || isSetSize_) {
71         return reduceSize;
72     }
73     if (GreatNotEqual(minIconSize_, (width_ - reduceSize))) {
74         int remain = reduceSize - (width_ - minIconSize_);
75         height_ = width_ = minIconSize_;
76         return remain;
77     }
78 
79     width_ -= reduceSize;
80     height_ = width_;
81     return 0.0;
82 }
83 
ShrinkHeight(double reduceSize)84 double IconLayoutElement::ShrinkHeight(double reduceSize)
85 {
86     if (!isExist_ || isSetSize_) {
87         return reduceSize;
88     }
89     if (GreatNotEqual(minIconSize_, (height_ - reduceSize))) {
90         double remain = reduceSize - (height_ - minIconSize_);
91         width_ = height_ = minIconSize_;
92         return remain;
93     }
94     height_ -= reduceSize;
95     width_ = height_;
96     return 0.0;
97 }
98 
Init(RefPtr<SecurityComponentLayoutProperty> & property,RefPtr<LayoutWrapper> & textWrap)99 void TextLayoutElement::Init(RefPtr<SecurityComponentLayoutProperty>& property,
100     RefPtr<LayoutWrapper>& textWrap)
101 {
102     secCompProperty_ = property;
103     textWrap_ = textWrap;
104     CHECK_NULL_VOID(property);
105     CHECK_NULL_VOID(textWrap);
106     if (property->GetSecurityComponentDescription().value_or(-1) ==
107             static_cast<int32_t>(SecurityComponentDescription::TEXT_NULL)) {
108         return;
109     }
110     isExist_ = true;
111 
112     auto textProp = AceType::DynamicCast<TextLayoutProperty>(textWrap_->GetLayoutProperty());
113     CHECK_NULL_VOID(textProp);
114     auto theme = PipelineContext::GetCurrentContext()->GetTheme<SecurityComponentTheme>();
115     CHECK_NULL_VOID(theme);
116     minFontSize_ = theme->GetMinFontSize();
117     if (property->GetFontSize().has_value()) {
118         isSetSize_ = true;
119     } else {
120         defaultFontSize_ = theme->GetFontSize();
121         textProp->UpdateFontSize(defaultFontSize_);
122     }
123 
124     auto textConstraint = property->CreateChildConstraint();
125     SizeT<float> maxSize { Infinity<float>(), Infinity<float>() };
126     textConstraint.maxSize = maxSize;
127     textWrap_->Measure(std::optional<LayoutConstraintF>(textConstraint));
128     auto textSizeF = textWrap->GetGeometryNode()->GetFrameSize();
129     width_ = textSizeF.Width();
130     height_ = textSizeF.Height();
131 }
132 
ChooseExactFontSize(RefPtr<TextLayoutProperty> & property,bool isWidth)133 void TextLayoutElement::ChooseExactFontSize(RefPtr<TextLayoutProperty>& property, bool isWidth)
134 {
135     if (!minTextSize_.has_value()) {
136         property->UpdateFontSize(minFontSize_);
137         return;
138     }
139     constexpr Dimension ADAPT_UNIT = 1.0_fp;
140     Dimension step = ADAPT_UNIT;
141     Dimension fontSize = (property->GetFontSize().has_value()) ? property->GetFontSize().value() : defaultFontSize_;
142     while (fontSize > minFontSize_) {
143         auto tempSize = GetMeasureTextSize(property->GetContent().value_or(""),
144             fontSize,
145             property->GetFontWeight().value_or(FontWeight::NORMAL));
146         if (!tempSize.has_value()) {
147             fontSize = minFontSize_;
148             break;
149         }
150         if (isWidth) {
151             if (GreatOrEqual(width_, tempSize.value().Width())) {
152                 break;
153             }
154         } else {
155             if (GreatOrEqual(height_, tempSize.value().Height())) {
156                 break;
157             }
158         }
159         fontSize -= step;
160     }
161     property->UpdateFontSize(fontSize);
162 }
163 
UpdateSize(bool isWidth)164 void TextLayoutElement::UpdateSize(bool isWidth)
165 {
166     auto textProp = AceType::DynamicCast<TextLayoutProperty>(textWrap_->GetLayoutProperty());
167     CHECK_NULL_VOID(textProp);
168     ChooseExactFontSize(textProp, isWidth);
169     auto textConstraint = textProp->GetContentLayoutConstraint();
170     CHECK_NULL_VOID(textConstraint);
171     if (isWidth) {
172         textConstraint->selfIdealSize.SetWidth(width_);
173     } else {
174         textConstraint->selfIdealSize.SetHeight(height_);
175     }
176 
177     textWrap_->Measure(textConstraint);
178     auto textSizeF = textWrap_->GetGeometryNode()->GetFrameSize();
179     width_ = textSizeF.Width();
180     height_ = textSizeF.Height();
181 }
182 
GetMeasureTextSize(const std::string & data,const Dimension & fontSize,FontWeight fontWeight)183 std::optional<SizeF> TextLayoutElement::GetMeasureTextSize(const std::string& data,
184     const Dimension& fontSize, FontWeight fontWeight)
185 {
186 #ifdef ENABLE_ROSEN_BACKEND
187     MeasureContext content;
188     content.textContent = data;
189     content.fontSize = fontSize;
190     auto fontweight = StringUtils::FontWeightToString(fontWeight);
191     content.fontWeight = fontweight;
192     auto size = RosenRenderCustomPaint::MeasureTextSizeInner(content);
193     return SizeF(size.Width(), size.Height());
194 #else
195     return std::nullopt;
196 #endif
197 }
198 
MeasureMinTextSize()199 void TextLayoutElement::MeasureMinTextSize()
200 {
201     auto textProp = AceType::DynamicCast<TextLayoutProperty>(textWrap_->GetLayoutProperty());
202     CHECK_NULL_VOID(textProp);
203     minTextSize_ = GetMeasureTextSize(textProp->GetContent().value_or(""),
204         minFontSize_,
205         textProp->GetFontWeight().value_or(FontWeight::NORMAL));
206 }
207 
ShrinkWidth(double reduceSize)208 double TextLayoutElement::ShrinkWidth(double reduceSize)
209 {
210     if (!isExist_ || isSetSize_) {
211         return reduceSize;
212     }
213     if (!minTextSize_.has_value()) {
214         MeasureMinTextSize();
215     }
216     double minTextWidth = minTextSize_.value_or(SizeT(0.0F, 0.0F)).Width();
217     if (GreatNotEqual(minTextWidth, (width_ - reduceSize))) {
218         int remain = reduceSize - (width_ - minTextWidth);
219         width_ = minTextWidth;
220         UpdateSize(true);
221         return remain;
222     }
223 
224     width_ -= reduceSize;
225     UpdateSize(true);
226     return 0.0;
227 }
228 
ShrinkHeight(double reduceSize)229 double TextLayoutElement::ShrinkHeight(double reduceSize)
230 {
231     if (!isExist_ || isSetSize_) {
232         return reduceSize;
233     }
234     if (!minTextSize_.has_value()) {
235         MeasureMinTextSize();
236     }
237 
238     double minTextHeight = minTextSize_.value_or(SizeT(0.0F, 0.0F)).Height();
239     if (GreatNotEqual(minTextHeight, (height_ - reduceSize))) {
240         double remain = reduceSize - (height_ - minTextHeight);
241         height_ = minTextHeight;
242         UpdateSize(false);
243         return remain;
244     }
245     height_ -= reduceSize;
246     UpdateSize(false);
247     return 0.0;
248 }
249 };
250