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