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 "frameworks/bridge/common/dom/dom_text.h"
17
18 #include "core/common/ace_application_info.h"
19 #include "core/components/declaration/text/text_declaration.h"
20 #include "frameworks/bridge/common/utils/utils.h"
21
22 namespace OHOS::Ace::Framework {
23
DOMText(NodeId nodeId,const std::string & nodeName)24 DOMText::DOMText(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
25 {
26 textChild_ = AceType::MakeRefPtr<TextComponent>("");
27 }
28
ResetInitializedStyle()29 void DOMText::ResetInitializedStyle()
30 {
31 if (declaration_) {
32 declaration_->InitializeStyle();
33 }
34 CheckAndSetAllSpanStyle();
35 }
36
CheckAndSetAllSpanStyle()37 void DOMText::CheckAndSetAllSpanStyle()
38 {
39 for (const auto& child : GetChildList()) {
40 auto domSpan = AceType::DynamicCast<DOMSpan>(child);
41 if (!domSpan) {
42 LOGW("text only support span child");
43 continue;
44 }
45 auto spanComponent = AceType::DynamicCast<TextSpanComponent>(domSpan->GetSpecializedComponent());
46 if (!spanComponent) {
47 LOGW("text only support span child");
48 continue;
49 }
50
51 // If span component has no developer-set styles, then set text styles to span
52 TextStyle spanStyle = spanComponent->GetTextStyle();
53 CheckAndSetSpanStyle(domSpan, spanStyle);
54 domSpan->SetTextStyle(spanStyle);
55 spanComponent->SetTextStyle(spanStyle);
56 }
57 }
58
CheckAndSetSpanStyle(const RefPtr<DOMSpan> & dmoSpan,TextStyle & spanStyle)59 void DOMText::CheckAndSetSpanStyle(const RefPtr<DOMSpan>& dmoSpan, TextStyle& spanStyle)
60 {
61 auto textDeclaration = AceType::DynamicCast<TextDeclaration>(declaration_);
62 if (!textDeclaration) {
63 return;
64 }
65
66 const auto& textStyle = textDeclaration->GetTextStyle();
67 if (!dmoSpan->HasSetFontSize()) {
68 LOGD("Set Text Font Size to Span");
69 spanStyle.SetFontSize(textStyle.GetFontSize());
70 }
71 if (!dmoSpan->HasSetFontStyle()) {
72 LOGD("Set Text Font Style to Span");
73 spanStyle.SetFontStyle(textStyle.GetFontStyle());
74 }
75 if (!dmoSpan->HasSetFontColor()) {
76 LOGD("Set Text Font Color to Span");
77 spanStyle.SetTextColor(textStyle.GetTextColor());
78 }
79 if (!dmoSpan->HasSetFontWeight()) {
80 LOGD("Set Text Font Weight to Span");
81 spanStyle.SetFontWeight(textStyle.GetFontWeight());
82 }
83 if (!dmoSpan->HasSetTextDecoration()) {
84 LOGD("Set Text Decoration to Span");
85 spanStyle.SetTextDecoration(textStyle.GetTextDecoration());
86 }
87 if (!dmoSpan->HasSetFontFamily()) {
88 LOGD("Set Text Font Family to Span");
89 spanStyle.SetFontFamilies(textStyle.GetFontFamilies());
90 }
91 if (!dmoSpan->HasSetAllowScale()) {
92 LOGD("Set Allow Scale to Span");
93 spanStyle.SetAllowScale(textStyle.IsAllowScale());
94 }
95 if (!dmoSpan->HasSetFontFeatures()) {
96 LOGD("Set Font Feature Settings to Span");
97 spanStyle.SetFontFeatures(textStyle.GetFontFeatures());
98 }
99 spanStyle.SetLetterSpacing(textStyle.GetLetterSpacing());
100 spanStyle.SetLineHeight(textStyle.GetLineHeight(), textStyle.HasHeightOverride());
101 }
102
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)103 void DOMText::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
104 {
105 ACE_DCHECK(child);
106 auto spanComponent = AceType::DynamicCast<TextSpanComponent>(child->GetSpecializedComponent());
107 if (!spanComponent) {
108 LOGW("text only support span child");
109 return;
110 }
111
112 // If span component has no developer-set styles, then set text styles to span
113 TextStyle spanStyle = spanComponent->GetTextStyle();
114 auto domSpan = AceType::DynamicCast<DOMSpan>(child);
115 ACE_DCHECK(domSpan);
116 CheckAndSetSpanStyle(domSpan, spanStyle);
117 domSpan->SetTextStyle(spanStyle);
118 spanComponent->SetTextStyle(spanStyle);
119 textChild_->InsertChild(slot, child->GetRootComponent());
120 }
121
OnChildNodeRemoved(const RefPtr<DOMNode> & child)122 void DOMText::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
123 {
124 ACE_DCHECK(child);
125 textChild_->RemoveChild(child->GetRootComponent());
126 }
127
PrepareSpecializedComponent()128 void DOMText::PrepareSpecializedComponent()
129 {
130 textChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
131
132 auto textDeclaration = AceType::DynamicCast<TextDeclaration>(declaration_);
133 if (!textDeclaration) {
134 return;
135 }
136 bool isCard = AceApplicationInfo::GetInstance().GetIsCardType();
137 if (isCard) {
138 auto& style = textDeclaration->MaybeResetStyle<TextSpecializedStyle>(StyleTag::SPECIALIZED_STYLE);
139 if (style.IsValid()) {
140 style.textStyle.SetAllowScale(false);
141 if (style.textStyle.GetFontSize().Unit() == DimensionUnit::FP) {
142 style.textStyle.SetAllowScale(true);
143 }
144 }
145 }
146 textDeclaration->SetIsMaxWidthLayout(boxComponent_->GetWidthDimension().IsValid());
147 CheckAndSetAllSpanStyle();
148 textChild_->SetDeclaration(textDeclaration);
149
150 // set box align
151 if (!textDeclaration->IsMaxWidthLayout()) {
152 SetBoxAlignForText();
153 }
154 }
155
SetBoxAlignForText()156 void DOMText::SetBoxAlignForText()
157 {
158 auto textDeclaration = AceType::DynamicCast<TextDeclaration>(declaration_);
159 if (!textDeclaration) {
160 return;
161 }
162
163 switch (textDeclaration->GetTextStyle().GetTextAlign()) {
164 case TextAlign::LEFT:
165 SetAlignment(Alignment::CENTER_LEFT);
166 break;
167 case TextAlign::CENTER:
168 SetAlignment(Alignment::CENTER);
169 break;
170 case TextAlign::RIGHT:
171 SetAlignment(Alignment::CENTER_RIGHT);
172 break;
173 case TextAlign::START:
174 SetAlignment(IsRightToLeft() ? Alignment::CENTER_RIGHT : Alignment::CENTER_LEFT);
175 break;
176 case TextAlign::END:
177 SetAlignment(IsRightToLeft() ? Alignment::CENTER_LEFT : Alignment::CENTER_RIGHT);
178 break;
179 default:
180 break;
181 }
182 }
183
184 } // namespace OHOS::Ace::Framework
185