• 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 
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 
VariantSpan(const std::shared_ptr<AnySpan> & as)27 VariantSpan::VariantSpan(const std::shared_ptr<AnySpan> &as) noexcept(true): as_(as) {}
28 
VariantSpan(std::shared_ptr<TextSpan> && ts)29 VariantSpan::VariantSpan(std::shared_ptr<TextSpan> &&ts) noexcept(true): ts_(std::move(ts)) {}
30 
VariantSpan(std::shared_ptr<AnySpan> && as)31 VariantSpan::VariantSpan(std::shared_ptr<AnySpan> &&as) noexcept(true): as_(std::move(as)) {}
32 
VariantSpan(std::nullptr_t)33 VariantSpan::VariantSpan(std::nullptr_t) noexcept(true) {}
34 
operator bool() const35 VariantSpan::operator bool() const noexcept(false)
36 {
37     CheckPointer(true);
38     return *this != nullptr;
39 }
40 
operator ==(std::nullptr_t) const41 bool VariantSpan::operator ==(std::nullptr_t) const noexcept(false)
42 {
43     CheckPointer(true);
44     return (ts_ == nullptr) && (as_ == nullptr);
45 }
46 
operator ==(const VariantSpan & rhs) const47 bool VariantSpan::operator ==(const VariantSpan &rhs) const noexcept(false)
48 {
49     CheckPointer(true);
50     return (ts_ == rhs.ts_) && (as_ == rhs.as_);
51 }
52 
operator !=(std::nullptr_t) const53 bool VariantSpan::operator !=(std::nullptr_t) const noexcept(false)
54 {
55     CheckPointer(true);
56     return !(*this == nullptr);
57 }
58 
operator !=(const VariantSpan & rhs) const59 bool VariantSpan::operator !=(const VariantSpan &rhs) const noexcept(false)
60 {
61     CheckPointer(true);
62     return !(*this == rhs);
63 }
64 
GetWidth() const65 double VariantSpan::GetWidth() const
66 {
67     CheckPointer();
68     if (as_) {
69         return as_->GetWidth();
70     }
71 
72     if (ts_) {
73         return ts_->GetWidth();
74     }
75 
76     return 0.0;
77 }
78 
GetHeight() const79 double VariantSpan::GetHeight() const noexcept(false)
80 {
81     CheckPointer();
82     if (as_) {
83         return as_->GetHeight();
84     }
85 
86     if (ts_) {
87         return ts_->GetHeight();
88     }
89 
90     return 0.0;
91 }
92 
GetNumberOfCharGroup() const93 size_t VariantSpan::GetNumberOfCharGroup() const noexcept(false)
94 {
95     CheckPointer();
96     if (ts_) {
97         return ts_->cgs_.GetNumberOfCharGroup();
98     }
99 
100     if (as_) {
101         return 1;
102     }
103 
104     return 0;
105 }
106 
GetGlyphWidths() const107 std::vector<double> VariantSpan::GetGlyphWidths() const noexcept(false)
108 {
109     CheckPointer();
110     std::vector<double> widths;
111     if (ts_) {
112         for (const auto &cg : ts_->cgs_) {
113             if (cg.IsEmoji()) {
114                 widths.push_back(cg.GetWidth());
115                 continue;
116             }
117             for (int i = 0; i < static_cast<int>(cg.chars.size()); i++) {
118                 widths.push_back(cg.GetWidth() / static_cast<int>(cg.chars.size()));
119             }
120         }
121     }
122 
123     if (as_) {
124         widths.push_back(GetWidth());
125     }
126 
127     return widths;
128 }
129 
GetVisibleWidth() const130 double VariantSpan::GetVisibleWidth() const noexcept(false)
131 {
132     CheckPointer();
133     if (ts_) {
134         double width = 0;
135         double continuousInvisibleWidth = 0;
136         for (const auto &cg : ts_->cgs_) {
137             width += (cg.visibleWidth + cg.invisibleWidth);
138             if (cg.visibleWidth > 0) {
139                 continuousInvisibleWidth = 0;
140             }
141             continuousInvisibleWidth += cg.invisibleWidth;
142         }
143         return width - continuousInvisibleWidth;
144     }
145 
146     if (as_) {
147         return as_->GetWidth();
148     }
149 
150     return 0.0;
151 }
152 
GetNumberOfChar() const153 size_t VariantSpan::GetNumberOfChar() const noexcept(false)
154 {
155     CheckPointer();
156     size_t count = 0;
157     if (ts_) {
158         for (const auto &cg : ts_->cgs_) {
159             if (cg.IsEmoji()) {
160                 count++;
161                 continue;
162             }
163             count += cg.chars.size();
164         }
165     }
166 
167     if (as_) {
168         // Set the number of AnySpan`s char to 1
169         return 1;
170     }
171 
172     return count;
173 }
174 
Dump(const DumpType & dtype) const175 void VariantSpan::Dump(const DumpType &dtype) const noexcept(false)
176 {
177     CheckPointer(true);
178     if (as_) {
179         switch (dtype) {
180             case DumpType::NORMAL:
181                 LOGEX_FUNC_LINE_DEBUG() << "VariantSpan";
182                 break;
183             case DumpType::DONT_RETURN:
184                 LOGEX_FUNC_LINE_DEBUG(Logger::SetToNoReturn) << "VariantSpan ";
185                 break;
186         }
187         return;
188     }
189 
190     if (ts_ == nullptr) {
191         return;
192     }
193 
194     switch (dtype) {
195         case DumpType::NORMAL:
196             LOGEX_FUNC_LINE_DEBUG() << "(" << offsetX_ << ", " << offsetY_ << ") " <<
197                 (ts_->rtl_ ? "<-" : "->") << " " << ts_->cgs_.GetRange() <<
198                 ": '\033[40m" << TextConverter::ToStr(ts_->cgs_.ToUTF16()) << "\033[0m'";
199             break;
200         case DumpType::DONT_RETURN:
201             LOGEX_FUNC_LINE_DEBUG(Logger::SetToNoReturn) << "(" << offsetX_ << ", " << offsetY_ << ") "<<
202                 (ts_->rtl_ ? "<-" : "->") << " " << ts_->cgs_.GetRange() <<
203                 ": '\033[40m" << TextConverter::ToStr(ts_->cgs_.ToUTF16()) << "\033[0m'" << " ";
204             break;
205     }
206 }
207 
TryToTextSpan() const208 std::shared_ptr<TextSpan> VariantSpan::TryToTextSpan() const noexcept(false)
209 {
210     CheckPointer(true);
211     return ts_;
212 }
213 
TryToAnySpan() const214 std::shared_ptr<AnySpan> VariantSpan::TryToAnySpan() const noexcept(false)
215 {
216     CheckPointer(true);
217     return as_;
218 }
219 
SetTextStyle(const TextStyle & xs)220 void VariantSpan::SetTextStyle(const TextStyle &xs) noexcept(true)
221 {
222     xs_ = std::move(xs);
223 }
224 
GetTextStyle()225 TextStyle &VariantSpan::GetTextStyle() noexcept(true)
226 {
227     return xs_;
228 }
229 
GetTextStyle() const230 const TextStyle &VariantSpan::GetTextStyle() const noexcept(true)
231 {
232     return xs_;
233 }
234 
GetOffsetX() const235 double VariantSpan::GetOffsetX() const noexcept(true)
236 {
237     return offsetX_;
238 }
239 
GetOffsetY() const240 double VariantSpan::GetOffsetY() const noexcept(true)
241 {
242     return offsetY_;
243 }
244 
AdjustOffsetX(double offset)245 void VariantSpan::AdjustOffsetX(double offset) noexcept(true)
246 {
247     offsetX_ += offset;
248 }
249 
AdjustOffsetY(double offset)250 void VariantSpan::AdjustOffsetY(double offset) noexcept(true)
251 {
252     offsetY_ += offset;
253 }
254 
Paint(TexgineCanvas & canvas,double offsetX,double offsetY)255 void VariantSpan::Paint(TexgineCanvas &canvas, double offsetX, double offsetY) noexcept(false)
256 {
257     CheckPointer();
258     if (as_) {
259         as_->SetTextStyle(xs_);
260         as_->SetRoundRectType(roundRectType_);
261         as_->Paint(canvas, offsetX, offsetY);
262     }
263 
264     if (ts_) {
265         ts_->Paint(canvas, offsetX, offsetY, xs_, roundRectType_);
266     }
267 }
268 
PaintShadow(TexgineCanvas & canvas,double offsetX,double offsetY)269 void VariantSpan::PaintShadow(TexgineCanvas &canvas, double offsetX, double offsetY) noexcept(false)
270 {
271     CheckPointer();
272     if (ts_) {
273         ts_->PaintShadow(canvas, offsetX, offsetY, xs_.shadows);
274     }
275 }
276 
IsRTL() const277 bool VariantSpan::IsRTL() const noexcept(false)
278 {
279     CheckPointer();
280     if (ts_) {
281         return ts_->IsRTL();
282     }
283 
284     return false;
285 }
286 
IsHardBreak() const287 bool VariantSpan::IsHardBreak() const noexcept(false)
288 {
289     CheckPointer();
290     return (ts_ && ts_->cgs_.GetBack().IsHardBreak());
291 }
292 
GetJustifyGap() const293 double VariantSpan::GetJustifyGap() const noexcept(true)
294 {
295     return justifyGap_;
296 }
297 
SetJustifyGap(double justifyGap)298 void VariantSpan::SetJustifyGap(double justifyGap) noexcept(true)
299 {
300     justifyGap_ = justifyGap;
301 }
302 
CheckPointer(bool nullable) const303 void VariantSpan::CheckPointer(bool nullable) const
304 {
305     if (!nullable && as_ == nullptr && ts_ == nullptr) {
306         throw TEXGINE_EXCEPTION(NULLPTR);
307     }
308 
309     if (as_ != nullptr && ts_ != nullptr) {
310         throw TEXGINE_EXCEPTION(ERROR_STATUS);
311     }
312 }
313 
HasBackgroundRect() const314 bool VariantSpan::HasBackgroundRect() const
315 {
316     return xs_.backgroundRect.color != 0 && GetWidth() > 0;
317 }
318 
GetRoundRectType() const319 RoundRectType VariantSpan::GetRoundRectType() const noexcept(true)
320 {
321     return roundRectType_;
322 }
323 
SetRoundRectType(RoundRectType type)324 void VariantSpan::SetRoundRectType(RoundRectType type) noexcept(true)
325 {
326     roundRectType_ = type;
327 }
328 
SetTopInGroup(double top)329 void VariantSpan::SetTopInGroup(double top)
330 {
331     CheckPointer();
332     if (as_) {
333         as_->SetTopInGroup(top);
334     }
335 
336     if (ts_) {
337         ts_->topInGroup_ = top;
338     }
339 }
340 
GetTopInGroup() const341 double VariantSpan::GetTopInGroup() const
342 {
343     double top = 0.0;
344     CheckPointer();
345     if (as_) {
346         top = as_->GetTopInGroup();
347     } else if (ts_) {
348         top = ts_->topInGroup_;
349     }
350     return top;
351 }
352 
SetBottomInGroup(double bottom)353 void VariantSpan::SetBottomInGroup(double bottom)
354 {
355     CheckPointer();
356     if (as_) {
357         as_->SetBottomInGroup(bottom);
358     }
359 
360     if (ts_) {
361         ts_->bottomInGroup_ = bottom;
362     }
363 }
364 
GetBottomInGroup() const365 double VariantSpan::GetBottomInGroup() const
366 {
367     double bottom = 0.0;
368     CheckPointer();
369     if (as_) {
370         bottom = as_->GetBottomInGroup();
371     } else if (ts_) {
372         bottom = ts_->bottomInGroup_;
373     }
374     return bottom;
375 }
376 
SetMaxRoundRectRadius(double radius)377 void VariantSpan::SetMaxRoundRectRadius(double radius)
378 {
379     CheckPointer();
380     if (as_) {
381         as_->SetMaxRoundRectRadius(radius);
382     }
383 
384     if (ts_) {
385         ts_->maxRoundRectRadius_ = radius;
386     }
387 }
388 
GetMaxRoundRectRadius() const389 double VariantSpan::GetMaxRoundRectRadius() const
390 {
391     double maxRoundRectRadius = 0.0;
392     CheckPointer();
393     if (as_) {
394         maxRoundRectRadius = as_->GetMaxRoundRectRadius();
395     } else if (ts_) {
396         maxRoundRectRadius = ts_->maxRoundRectRadius_;
397     }
398     return maxRoundRectRadius;
399 }
400 
GetTop() const401 double VariantSpan::GetTop() const noexcept(true)
402 {
403     double top = offsetY_;
404     if (ts_) {
405         top += *(ts_->tmetrics_->fAscent_);
406     }
407     return top;
408 }
409 
GetBottom() const410 double VariantSpan::GetBottom() const noexcept(true)
411 {
412     double bottom = GetTop();
413     if (ts_) {
414         bottom += (*(ts_->tmetrics_->fDescent_) - *(ts_->tmetrics_->fAscent_));
415     } else if (as_) {
416         bottom += as_->GetHeight();
417     }
418     return bottom;
419 }
420 } // namespace TextEngine
421 } // namespace Rosen
422 } // namespace OHOS
423