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
16 #include "variant_span.h"
17
18 #include "texgine_exception.h"
19 #include "texgine/utils/exlog.h"
20 #include "text_converter.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 namespace TextEngine {
VariantSpan(const std::shared_ptr<TextSpan> & ts)25 VariantSpan::VariantSpan(const std::shared_ptr<TextSpan> &ts) noexcept(true): ts_(ts)
26 {
27 }
28
VariantSpan(const std::shared_ptr<AnySpan> & as)29 VariantSpan::VariantSpan(const std::shared_ptr<AnySpan> &as) noexcept(true): as_(as)
30 {
31 }
32
VariantSpan(std::shared_ptr<TextSpan> && ts)33 VariantSpan::VariantSpan(std::shared_ptr<TextSpan> &&ts) noexcept(true): ts_(std::move(ts))
34 {
35 }
36
VariantSpan(std::shared_ptr<AnySpan> && as)37 VariantSpan::VariantSpan(std::shared_ptr<AnySpan> &&as) noexcept(true): as_(std::move(as))
38 {
39 }
40
VariantSpan(std::nullptr_t)41 VariantSpan::VariantSpan(std::nullptr_t) noexcept(true)
42 {
43 }
44
operator bool() const45 VariantSpan::operator bool() const noexcept(false)
46 {
47 CheckPointer(true);
48 return *this != nullptr;
49 }
50
operator ==(std::nullptr_t) const51 bool VariantSpan::operator ==(std::nullptr_t) const noexcept(false)
52 {
53 CheckPointer(true);
54 return (ts_ == nullptr) && (as_ == nullptr);
55 }
56
operator ==(const VariantSpan & rhs) const57 bool VariantSpan::operator ==(const VariantSpan &rhs) const noexcept(false)
58 {
59 CheckPointer(true);
60 return (ts_ == rhs.ts_) && (as_ == rhs.as_);
61 }
62
operator !=(std::nullptr_t) const63 bool VariantSpan::operator !=(std::nullptr_t) const noexcept(false)
64 {
65 CheckPointer(true);
66 return !(*this == nullptr);
67 }
68
operator !=(const VariantSpan & rhs) const69 bool VariantSpan::operator !=(const VariantSpan &rhs) const noexcept(false)
70 {
71 CheckPointer(true);
72 return !(*this == rhs);
73 }
74
GetWidth() const75 double VariantSpan::GetWidth() const noexcept(false)
76 {
77 CheckPointer();
78 if (as_) {
79 return as_->GetWidth();
80 }
81
82 if (ts_) {
83 return ts_->GetWidth();
84 }
85
86 return 0.0;
87 }
88
GetHeight() const89 double VariantSpan::GetHeight() const noexcept(false)
90 {
91 CheckPointer();
92 if (as_) {
93 return as_->GetHeight();
94 }
95
96 if (ts_) {
97 return ts_->GetHeight();
98 }
99
100 return 0.0;
101 }
102
GetNumberOfCharGroup() const103 size_t VariantSpan::GetNumberOfCharGroup() const noexcept(false)
104 {
105 CheckPointer();
106 if (ts_) {
107 return ts_->cgs_.GetNumberOfCharGroup();
108 }
109
110 if (as_) {
111 return 1;
112 }
113
114 return 0;
115 }
116
GetGlyphWidths() const117 std::vector<double> VariantSpan::GetGlyphWidths() const noexcept(false)
118 {
119 CheckPointer();
120 std::vector<double> widths;
121 if (ts_) {
122 for (const auto &cg : ts_->cgs_) {
123 widths.push_back(cg.GetWidth());
124 }
125 }
126
127 if (as_) {
128 widths.push_back(GetWidth());
129 }
130
131 return widths;
132 }
133
GetVisibleWidth() const134 double VariantSpan::GetVisibleWidth() const noexcept(false)
135 {
136 CheckPointer();
137 if (ts_) {
138 double width = 0;
139 double continuousInvisibleWidth = 0;
140 for (const auto &cg : ts_->cgs_) {
141 width += (cg.visibleWidth + cg.invisibleWidth);
142 if (cg.visibleWidth > 0) {
143 continuousInvisibleWidth = 0;
144 }
145 continuousInvisibleWidth += cg.invisibleWidth;
146 }
147 return width - continuousInvisibleWidth;
148 }
149
150 if (as_) {
151 return as_->GetWidth();
152 }
153
154 return 0.0;
155 }
156
Dump(const DumpType & dtype) const157 void VariantSpan::Dump(const DumpType &dtype) const noexcept(false)
158 {
159 CheckPointer(true);
160 if (as_) {
161 switch (dtype) {
162 case DumpType::NORMAL:
163 LOGEX_FUNC_LINE_DEBUG() << "VariantSpan";
164 break;
165 case DumpType::DONT_RETURN:
166 LOGEX_FUNC_LINE_DEBUG(Logger::SetToNoReturn) << "VariantSpan ";
167 break;
168 }
169 return;
170 }
171
172 if (ts_ == nullptr) {
173 return;
174 }
175
176 switch (dtype) {
177 case DumpType::NORMAL:
178 LOGEX_FUNC_LINE_DEBUG() << "(" << offsetX_ << ", " << offsetY_ << ") " <<
179 (ts_->rtl_ ? "<-" : "->") << " " << ts_->cgs_.GetRange() <<
180 ": '\033[40m" << TextConverter::ToStr(ts_->cgs_.ToUTF16()) << "\033[0m'";
181 break;
182 case DumpType::DONT_RETURN:
183 LOGEX_FUNC_LINE_DEBUG(Logger::SetToNoReturn) << "(" << offsetX_ << ", " << offsetY_ << ") "<<
184 (ts_->rtl_ ? "<-" : "->") << " " << ts_->cgs_.GetRange() <<
185 ": '\033[40m" << TextConverter::ToStr(ts_->cgs_.ToUTF16()) << "\033[0m'" << " ";
186 break;
187 }
188 }
189
TryToTextSpan() const190 std::shared_ptr<TextSpan> VariantSpan::TryToTextSpan() const noexcept(false)
191 {
192 CheckPointer(true);
193 return ts_;
194 }
195
TryToAnySpan() const196 std::shared_ptr<AnySpan> VariantSpan::TryToAnySpan() const noexcept(false)
197 {
198 CheckPointer(true);
199 return as_;
200 }
201
SetTextStyle(const TextStyle & xs)202 void VariantSpan::SetTextStyle(const TextStyle &xs) noexcept(true)
203 {
204 xs_ = std::move(xs);
205 }
206
GetTextStyle()207 TextStyle &VariantSpan::GetTextStyle() noexcept(true)
208 {
209 return xs_;
210 }
211
GetTextStyle() const212 const TextStyle &VariantSpan::GetTextStyle() const noexcept(true)
213 {
214 return xs_;
215 }
216
GetOffsetX() const217 double VariantSpan::GetOffsetX() const noexcept(true)
218 {
219 return offsetX_;
220 }
221
GetOffsetY() const222 double VariantSpan::GetOffsetY() const noexcept(true)
223 {
224 return offsetY_;
225 }
226
AdjustOffsetX(double offset)227 void VariantSpan::AdjustOffsetX(double offset) noexcept(true)
228 {
229 offsetX_ += offset;
230 }
231
AdjustOffsetY(double offset)232 void VariantSpan::AdjustOffsetY(double offset) noexcept(true)
233 {
234 offsetY_ += offset;
235 }
236
Paint(TexgineCanvas & canvas,double offsetX,double offsetY)237 void VariantSpan::Paint(TexgineCanvas &canvas, double offsetX, double offsetY) noexcept(false)
238 {
239 CheckPointer();
240 if (as_) {
241 as_->Paint(canvas, offsetX, offsetY);
242 }
243
244 if (ts_) {
245 ts_->Paint(canvas, offsetX, offsetY, xs_);
246 }
247 }
248
PaintShadow(TexgineCanvas & canvas,double offsetX,double offsetY)249 void VariantSpan::PaintShadow(TexgineCanvas &canvas, double offsetX, double offsetY) noexcept(false)
250 {
251 CheckPointer();
252 if (ts_) {
253 ts_->PaintShadow(canvas, offsetX, offsetY, xs_.shadows);
254 }
255 }
256
IsRTL() const257 bool VariantSpan::IsRTL() const noexcept(false)
258 {
259 CheckPointer();
260 if (ts_) {
261 return ts_->IsRTL();
262 }
263
264 return false;
265 }
266
CheckPointer(bool nullable) const267 void VariantSpan::CheckPointer(bool nullable) const noexcept(false)
268 {
269 if (!nullable && as_ == nullptr && ts_ == nullptr) {
270 throw TEXGINE_EXCEPTION(NULLPTR);
271 }
272
273 if (as_ != nullptr && ts_ != nullptr) {
274 throw TEXGINE_EXCEPTION(ERROR_STATUS);
275 }
276 }
277 } // namespace TextEngine
278 } // namespace Rosen
279 } // namespace OHOS
280