• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "typography.h"
17 
18 #include <mutex>
19 #include <numeric>
20 
21 #include "convert.h"
22 #include "impl/paragraph_impl.h"
23 #include "modules/skparagraph/include/TextStyle.h"
24 #include "skia_adapter/skia_canvas.h"
25 #include "skia_adapter/skia_convert_utils.h"
26 #include "text_line_base.h"
27 #include "text_style.h"
28 #include "txt/paragraph_style.h"
29 #include "txt/text_style.h"
30 #include "typography_style.h"
31 #include "utils/text_log.h"
32 #include "utils/text_trace.h"
33 
34 namespace OHOS {
35 namespace Rosen {
36 namespace skt = skia::textlayout;
37 
TextRect(Drawing::RectF rec,TextDirection dir)38 TextRect::TextRect(Drawing::RectF rec, TextDirection dir)
39 {
40     rect = rec;
41     direction = dir;
42 }
43 
IndexAndAffinity(size_t charIndex,Affinity charAffinity)44 IndexAndAffinity::IndexAndAffinity(size_t charIndex, Affinity charAffinity)
45 {
46     index = charIndex;
47     affinity = charAffinity;
48 }
49 
50 namespace AdapterTxt {
Typography(std::unique_ptr<SPText::Paragraph> paragraph)51 Typography::Typography(std::unique_ptr<SPText::Paragraph> paragraph): paragraph_(std::move(paragraph))
52 {
53 }
54 
GetMaxWidth() const55 double Typography::GetMaxWidth() const
56 {
57     std::shared_lock<std::shared_mutex> readLock(mutex_);
58     return paragraph_->GetMaxWidth();
59 }
60 
GetHeight() const61 double Typography::GetHeight() const
62 {
63     std::shared_lock<std::shared_mutex> readLock(mutex_);
64     return paragraph_->GetHeight();
65 }
66 
GetActualWidth() const67 double Typography::GetActualWidth() const
68 {
69     std::shared_lock<std::shared_mutex> readLock(mutex_);
70     return paragraph_->GetLongestLine();
71 }
72 
GetLongestLineWithIndent() const73 double Typography::GetLongestLineWithIndent() const
74 {
75     std::shared_lock<std::shared_mutex> readLock(mutex_);
76     return paragraph_->GetLongestLineWithIndent();
77 }
78 
GetMinIntrinsicWidth()79 double Typography::GetMinIntrinsicWidth()
80 {
81     std::shared_lock<std::shared_mutex> readLock(mutex_);
82     return paragraph_->GetMinIntrinsicWidth();
83 }
84 
GetMaxIntrinsicWidth()85 double Typography::GetMaxIntrinsicWidth()
86 {
87     std::shared_lock<std::shared_mutex> readLock(mutex_);
88     return paragraph_->GetMaxIntrinsicWidth();
89 }
90 
GetAlphabeticBaseline()91 double Typography::GetAlphabeticBaseline()
92 {
93     std::shared_lock<std::shared_mutex> readLock(mutex_);
94     return paragraph_->GetAlphabeticBaseline();
95 }
96 
GetIdeographicBaseline()97 double Typography::GetIdeographicBaseline()
98 {
99     std::shared_lock<std::shared_mutex> readLock(mutex_);
100     return paragraph_->GetIdeographicBaseline();
101 }
102 
DidExceedMaxLines() const103 bool Typography::DidExceedMaxLines() const
104 {
105     std::shared_lock<std::shared_mutex> readLock(mutex_);
106     return paragraph_->DidExceedMaxLines();
107 }
108 
GetLineCount() const109 int Typography::GetLineCount() const
110 {
111     std::shared_lock<std::shared_mutex> readLock(mutex_);
112     return paragraph_->GetLineCount();
113 }
114 
SetIndents(const std::vector<float> & indents)115 void Typography::SetIndents(const std::vector<float>& indents)
116 {
117     std::unique_lock<std::shared_mutex> writeLock(mutex_);
118     paragraph_->SetIndents(indents);
119 }
120 
DetectIndents(size_t index)121 float Typography::DetectIndents(size_t index)
122 {
123     std::shared_lock<std::shared_mutex> readLock(mutex_);
124     return paragraph_->DetectIndents(index);
125 }
126 
Relayout(double width,const TypographyStyle & typograhyStyle,const std::vector<TextStyle> & textStyles)127 void Typography::Relayout(double width, const TypographyStyle &typograhyStyle, const std::vector<TextStyle> &textStyles)
128 {
129     std::unique_lock<std::shared_mutex> writeLock(mutex_);
130 
131     if (!paragraph_->IsLayoutDone()) {
132         TEXT_LOGI_LIMIT3_MIN("Need to layout first");
133         return;
134     }
135 
136     bool isTextStyleChange = std::any_of(textStyles.begin(), textStyles.end(), [](const TextStyle& style) {
137         return style.relayoutChangeBitmap.any() || style.symbol.GetSymbolBitmap().any();
138     });
139     if (!typograhyStyle.relayoutChangeBitmap.any() && !isTextStyleChange) {
140         if (skt::nearlyEqual(paragraph_->GetMaxWidth(), width)) {
141             TEXT_LOGI_LIMIT3_MIN("No relayout required");
142             return;
143         }
144         paragraph_->SetLayoutState(skt::InternalState::kShaped);
145 
146         paragraph_->Layout(width);
147     } else {
148         SPText::ParagraphStyle paragraphStyle = Convert(typograhyStyle);
149         std::vector<SPText::TextStyle> spTextStyles;
150         for (const TextStyle& style : textStyles) {
151             spTextStyles.push_back(Convert(style));
152         }
153 
154         paragraph_->Relayout(width, paragraphStyle, spTextStyles);
155     }
156     lineMetrics_.reset();
157     lineMetricsStyles_.clear();
158 }
159 
Layout(double width)160 void Typography::Layout(double width)
161 {
162     TEXT_TRACE_FUNC();
163     std::unique_lock<std::shared_mutex> writeLock(mutex_);
164     lineMetrics_.reset();
165     lineMetricsStyles_.clear();
166     return paragraph_->Layout(width);
167 }
168 
GetGlyphsBoundsTop()169 double Typography::GetGlyphsBoundsTop()
170 {
171     std::shared_lock<std::shared_mutex> readLock(mutex_);
172     return paragraph_->GetGlyphsBoundsTop();
173 }
174 
GetGlyphsBoundsBottom()175 double Typography::GetGlyphsBoundsBottom()
176 {
177     std::shared_lock<std::shared_mutex> readLock(mutex_);
178     return paragraph_->GetGlyphsBoundsBottom();
179 }
180 
GetGlyphsBoundsLeft()181 double Typography::GetGlyphsBoundsLeft()
182 {
183     std::shared_lock<std::shared_mutex> readLock(mutex_);
184     return paragraph_->GetGlyphsBoundsLeft();
185 }
186 
GetGlyphsBoundsRight()187 double Typography::GetGlyphsBoundsRight()
188 {
189     std::shared_lock<std::shared_mutex> readLock(mutex_);
190     return paragraph_->GetGlyphsBoundsRight();
191 }
192 
MeasureText()193 Drawing::FontMetrics Typography::MeasureText()
194 {
195     std::unique_lock<std::shared_mutex> writeLock(mutex_);
196     return paragraph_->MeasureText();
197 }
198 
MarkDirty()199 void Typography::MarkDirty()
200 {
201     std::unique_lock<std::shared_mutex> writeLock(mutex_);
202     if (paragraph_ == nullptr) {
203         return;
204     }
205     paragraph_->MarkDirty();
206 }
207 
GetUnresolvedGlyphsCount()208 int32_t Typography::GetUnresolvedGlyphsCount()
209 {
210     std::shared_lock<std::shared_mutex> readLock(mutex_);
211     if (paragraph_ == nullptr) {
212         return 0;
213     }
214     return paragraph_->GetUnresolvedGlyphsCount();
215 }
216 
UpdateFontSize(size_t from,size_t to,float fontSize)217 void Typography::UpdateFontSize(size_t from, size_t to, float fontSize)
218 {
219     std::unique_lock<std::shared_mutex> writeLock(mutex_);
220     if (paragraph_ == nullptr) {
221         return;
222     }
223     paragraph_->UpdateFontSize(from, to, fontSize);
224 }
225 
Paint(SkCanvas * canvas,double x,double y)226 void Typography::Paint(SkCanvas *canvas, double x, double y)
227 {
228     std::unique_lock<std::shared_mutex> writeLock(mutex_);
229     return paragraph_->Paint(canvas, x, y);
230 }
231 
Paint(Drawing::Canvas * drawCanvas,double x,double y)232 void Typography::Paint(Drawing::Canvas *drawCanvas, double x, double y)
233 {
234     std::unique_lock<std::shared_mutex> writeLock(mutex_);
235     paragraph_->Paint(drawCanvas, x, y);
236 }
237 
Paint(Drawing::Canvas * drawCanvas,Drawing::Path * path,double hOffset,double vOffset)238 void Typography::Paint(Drawing::Canvas* drawCanvas, Drawing::Path* path, double hOffset, double vOffset)
239 {
240     std::unique_lock<std::shared_mutex> writeLock(mutex_);
241     paragraph_->Paint(drawCanvas, path, hOffset, vOffset);
242 }
243 
GetTextRectsByBoundary(size_t left,size_t right,TextRectHeightStyle heightStyle,TextRectWidthStyle widthStyle)244 std::vector<TextRect> Typography::GetTextRectsByBoundary(size_t left, size_t right,
245     TextRectHeightStyle heightStyle, TextRectWidthStyle widthStyle)
246 {
247     std::shared_lock<std::shared_mutex> readLock(mutex_);
248     auto txtRectHeightStyle = Convert(heightStyle);
249     auto txtRectWidthStyle = Convert(widthStyle);
250     auto rects = paragraph_->GetRectsForRange(left, right, txtRectHeightStyle, txtRectWidthStyle);
251 
252     std::vector<TextRect> boxes;
253     for (const auto &rect : rects) {
254         boxes.push_back(Convert(rect));
255     }
256     return boxes;
257 }
258 
GetTextRectsOfPlaceholders()259 std::vector<TextRect> Typography::GetTextRectsOfPlaceholders()
260 {
261     std::shared_lock<std::shared_mutex> readLock(mutex_);
262     auto rects = paragraph_->GetRectsForPlaceholders();
263 
264     std::vector<TextRect> boxes;
265     for (const auto &rect : rects) {
266         boxes.push_back(Convert(rect));
267     }
268     return boxes;
269 }
270 
GetGlyphIndexByCoordinate(double x,double y)271 IndexAndAffinity Typography::GetGlyphIndexByCoordinate(double x, double y)
272 {
273     std::shared_lock<std::shared_mutex> readLock(mutex_);
274     auto pos = paragraph_->GetGlyphPositionAtCoordinate(x, y);
275     return Convert(pos);
276 }
277 
GetWordBoundaryByIndex(size_t index)278 Boundary Typography::GetWordBoundaryByIndex(size_t index)
279 {
280     std::shared_lock<std::shared_mutex> readLock(mutex_);
281     auto range = paragraph_->GetWordBoundary(index);
282     return Convert(range);
283 }
284 
GetActualTextRange(int lineNumber,bool includeSpaces)285 Boundary Typography::GetActualTextRange(int lineNumber, bool includeSpaces)
286 {
287     std::shared_lock<std::shared_mutex> readLock(mutex_);
288     auto range = paragraph_->GetActualTextRange(lineNumber, includeSpaces);
289     return Convert(range);
290 }
291 
GetEllipsisTextRange()292 Boundary Typography::GetEllipsisTextRange()
293 {
294     std::shared_lock<std::shared_mutex> readLock(mutex_);
295     auto range = paragraph_->GetEllipsisTextRange();
296     return Convert(range);
297 }
298 
GetLineHeight(int lineNumber)299 double Typography::GetLineHeight(int lineNumber)
300 {
301     std::shared_lock<std::shared_mutex> readLock(mutex_);
302     const auto &lines = paragraph_->GetLineMetrics();
303     if ((0 <= lineNumber) && (lineNumber < static_cast<int>(lines.size()))) {
304         return lines[lineNumber].fHeight;
305     }
306     return 0.0;
307 }
308 
GetLineWidth(int lineNumber)309 double Typography::GetLineWidth(int lineNumber)
310 {
311     std::shared_lock<std::shared_mutex> readLock(mutex_);
312     const auto &lines = paragraph_->GetLineMetrics();
313     if ((0 <= lineNumber) && (lineNumber < static_cast<int>(lines.size()))) {
314         return lines[lineNumber].fWidth;
315     }
316     return 0.0;
317 }
318 
SetAnimation(std::function<bool (const std::shared_ptr<OHOS::Rosen::TextEngine::SymbolAnimationConfig> &)> & animationFunc)319 void Typography::SetAnimation(
320     std::function<bool(const std::shared_ptr<OHOS::Rosen::TextEngine::SymbolAnimationConfig>&)>& animationFunc
321 )
322 {
323     std::unique_lock<std::shared_mutex> writeLock(mutex_);
324     if (animationFunc != nullptr && paragraph_ != nullptr) {
325         paragraph_->SetAnimation(animationFunc);
326     }
327 }
328 
GetAnimation()329 std::function<bool(const std::shared_ptr<TextEngine::SymbolAnimationConfig>&)> Typography::GetAnimation()
330 {
331     std::shared_lock<std::shared_mutex> readLock(mutex_);
332     if (paragraph_ == nullptr) {
333         return nullptr;
334     }
335     return paragraph_->GetAnimation();
336 }
337 
SetParagraghId(uint32_t id)338 void Typography::SetParagraghId(uint32_t id)
339 {
340     std::unique_lock<std::shared_mutex> writeLock(mutex_);
341     if (paragraph_ != nullptr) {
342         paragraph_->SetParagraghId(id);
343     }
344 }
345 
GetLineInfo(int lineNumber,bool oneLine,bool includeWhitespace,LineMetrics * lineMetrics)346 bool Typography::GetLineInfo(int lineNumber, bool oneLine, bool includeWhitespace, LineMetrics* lineMetrics)
347 {
348     std::shared_lock<std::shared_mutex> readLock(mutex_);
349     if (paragraph_ == nullptr) {
350         return false;
351     }
352     if (lineNumber < 0 || lineNumber >= static_cast<int>(paragraph_->GetLineCount()) || lineMetrics == nullptr) {
353         return false;
354     }
355 
356     skia::textlayout::LineMetrics sklineMetrics;
357     if (!paragraph_->GetLineMetricsAt(lineNumber, &sklineMetrics)) {
358         return false;
359     }
360 
361     if (!sklineMetrics.fLineMetrics.empty()) {
362         const auto &skFontMetrics = sklineMetrics.fLineMetrics.begin()->second.font_metrics;
363         lineMetrics->firstCharMetrics = skFontMetrics;
364         if (oneLine) {
365             lineMetrics->ascender = sklineMetrics.fAscent;
366             lineMetrics->descender = sklineMetrics.fDescent;
367         } else {
368             lineMetrics->ascender = skFontMetrics.fAscent;
369             lineMetrics->descender = skFontMetrics.fDescent;
370         }
371         lineMetrics->capHeight = skFontMetrics.fCapHeight;
372         lineMetrics->xHeight = skFontMetrics.fXHeight;
373     } else {
374         if (oneLine) {
375             lineMetrics->ascender = sklineMetrics.fAscent;
376             lineMetrics->descender = sklineMetrics.fDescent;
377         } else {
378             lineMetrics->ascender = 0.0;
379             lineMetrics->descender = 0.0;
380         }
381         lineMetrics->capHeight = 0.0;
382         lineMetrics->xHeight = 0.0;
383     }
384     if (includeWhitespace) {
385         lineMetrics->width = sklineMetrics.fWidthWithSpaces;
386     } else {
387         lineMetrics->width = sklineMetrics.fWidth;
388     }
389     lineMetrics->height = sklineMetrics.fHeight;
390     lineMetrics->x = sklineMetrics.fLeft;
391     lineMetrics->y = sklineMetrics.fTopHeight;
392     lineMetrics->startIndex = sklineMetrics.fStartIndex;
393     lineMetrics->endIndex = sklineMetrics.fEndIndex;
394 
395     return true;
396 }
397 
GetLineMetrics()398 std::vector<LineMetrics> Typography::GetLineMetrics()
399 {
400     std::unique_lock<std::shared_mutex> writeLock(mutex_);
401     if (lineMetrics_) {
402         return lineMetrics_.value();
403     }
404     lineMetrics_.emplace();
405     if (paragraph_ != nullptr) {
406         auto metrics = paragraph_->GetLineMetrics();
407         lineMetricsStyles_.reserve(std::accumulate(metrics.begin(), metrics.end(), 0,
408             [](const int a, const skia::textlayout::LineMetrics& b) { return a + b.fLineMetrics.size(); }));
409 
410         for (const skt::LineMetrics& skLineMetrics : metrics) {
411             LineMetrics& line = lineMetrics_->emplace_back();
412             if (!skLineMetrics.fLineMetrics.empty()) {
413                 const auto &skmFontMetrics = skLineMetrics.fLineMetrics.begin()->second.font_metrics;
414                 line.firstCharMetrics = skmFontMetrics;
415                 line.capHeight = skmFontMetrics.fCapHeight;
416                 line.xHeight = skmFontMetrics.fXHeight;
417             } else {
418                 line.capHeight = 0.0;
419                 line.xHeight = 0.0;
420             }
421             line.lineNumber = skLineMetrics.fLineNumber;
422             line.baseline = skLineMetrics.fBaseline;
423             line.ascender = skLineMetrics.fAscent;
424             line.descender = skLineMetrics.fDescent;
425             line.width = skLineMetrics.fWidth;
426             line.height = skLineMetrics.fHeight;
427             line.x = skLineMetrics.fLeft;
428             line.y = skLineMetrics.fTopHeight;
429             line.startIndex = skLineMetrics.fStartIndex;
430             line.endIndex = skLineMetrics.fEndIndex;
431             for (const auto& [index, styleMtrics] : skLineMetrics.fLineMetrics) {
432                 SPText::TextStyle spTextStyle = paragraph_->SkStyleToTextStyle(*styleMtrics.text_style);
433                 lineMetricsStyles_.emplace_back(Convert(spTextStyle));
434 
435                 line.runMetrics.emplace(std::piecewise_construct, std::forward_as_tuple(index),
436                     std::forward_as_tuple(&lineMetricsStyles_.back(), styleMtrics.font_metrics));
437             }
438         }
439     }
440     return lineMetrics_.value();
441 }
442 
GetLineMetricsAt(int lineNumber,LineMetrics * lineMetrics)443 bool Typography::GetLineMetricsAt(int lineNumber, LineMetrics* lineMetrics)
444 {
445     if (paragraph_ == nullptr) {
446         return false;
447     }
448     if (lineNumber < 0 || lineNumber >= static_cast<int>(paragraph_->GetLineCount()) || lineMetrics == nullptr) {
449         return false;
450     }
451     std::vector<LineMetrics> vecLineMetrics = GetLineMetrics();
452 
453     if (vecLineMetrics.empty()) {
454         return false;
455     }
456 
457     *lineMetrics = vecLineMetrics[lineNumber];
458 
459     return true;
460 }
461 
GetFontMetrics(const OHOS::Rosen::TextStyle & textStyle)462 Drawing::FontMetrics Typography::GetFontMetrics(const OHOS::Rosen::TextStyle& textStyle)
463 {
464     std::shared_lock<std::shared_mutex> readLock(mutex_);
465     auto spTextStyle = Convert(textStyle);
466     return paragraph_->GetFontMetricsResult(spTextStyle);
467 }
468 
GetLineFontMetrics(const size_t lineNumber,size_t & charNumber,std::vector<Drawing::FontMetrics> & fontMetrics)469 bool Typography::GetLineFontMetrics(const size_t lineNumber,
470     size_t& charNumber, std::vector<Drawing::FontMetrics>& fontMetrics)
471 {
472     std::shared_lock<std::shared_mutex> readLock(mutex_);
473     if (!paragraph_) {
474         return false;
475     }
476     return paragraph_->GetLineFontMetrics(lineNumber, charNumber, fontMetrics);
477 }
478 
GetTextLines() const479 std::vector<std::unique_ptr<TextLineBase>> Typography::GetTextLines() const
480 {
481     std::shared_lock<std::shared_mutex> readLock(mutex_);
482     if (!paragraph_) {
483         return {};
484     }
485     std::vector<std::unique_ptr<SPText::TextLineBase>> textLines = paragraph_->GetTextLines();
486     std::vector<std::unique_ptr<TextLineBase>> lines;
487 
488     for (std::unique_ptr<SPText::TextLineBase>& textLine : textLines) {
489         std::unique_ptr<TextLineBaseImpl> linePtr = std::make_unique<TextLineBaseImpl>(std::move(textLine));
490         lines.emplace_back(std::move(linePtr));
491     }
492     return lines;
493 }
494 
CloneSelf()495 std::unique_ptr<OHOS::Rosen::Typography> Typography::CloneSelf()
496 {
497     std::shared_lock<std::shared_mutex> readLock(mutex_);
498     if (!paragraph_) {
499         return nullptr;
500     }
501     return std::make_unique<Typography>(paragraph_->CloneSelf());
502 }
503 
UpdateColor(size_t from,size_t to,const Drawing::Color & color)504 void Typography::UpdateColor(size_t from, size_t to, const Drawing::Color& color)
505 {
506     std::unique_lock<std::shared_mutex> writeLock(mutex_);
507     if (!paragraph_) {
508         return;
509     }
510     paragraph_->UpdateColor(from, to, color);
511 }
512 
UpdateAllTextStyles(const TextStyle & textStyleTemplate)513 void Typography::UpdateAllTextStyles(const TextStyle& textStyleTemplate)
514 {
515     std::unique_lock<std::shared_mutex> writeLock(mutex_);
516     if (!paragraph_) {
517         return;
518     }
519     std::vector<SPText::TextStyle> spTextStyles;
520     spTextStyles.push_back(Convert(textStyleTemplate));
521     paragraph_->ApplyTextStyleChanges(spTextStyles);
522 }
523 
GeneratePaintRegion(double x,double y) const524 Drawing::RectI Typography::GeneratePaintRegion(double x, double y) const
525 {
526     std::unique_lock<std::shared_mutex> writeLock(mutex_);
527     if (!paragraph_) {
528         double left = std::floor(x);
529         double top = std::floor(y);
530         return Drawing::RectI(left, top, left, top);
531     }
532 
533     return paragraph_->GeneratePaintRegion(x, y);
534 }
535 
GetTextBlobRecordInfo() const536 std::vector<TextBlobRecordInfo> Typography::GetTextBlobRecordInfo() const
537 {
538     std::shared_lock<std::shared_mutex> readLock(mutex_);
539     if (paragraph_ == nullptr) {
540         return {};
541     }
542     return paragraph_->GetTextBlobRecordInfo();
543 }
544 
HasSkipTextBlobDrawing() const545 bool Typography::HasSkipTextBlobDrawing() const
546 {
547     std::shared_lock<std::shared_mutex> readLock(mutex_);
548     if (paragraph_ == nullptr) {
549         return false;
550     }
551     return paragraph_->HasSkipTextBlobDrawing();
552 }
553 
SetSkipTextBlobDrawing(bool state)554 void Typography::SetSkipTextBlobDrawing(bool state)
555 {
556     std::unique_lock<std::shared_mutex> writeLock(mutex_);
557     if (paragraph_ == nullptr) {
558         return;
559     }
560     paragraph_->SetSkipTextBlobDrawing(state);
561 }
562 
CanPaintAllText() const563 bool Typography::CanPaintAllText() const
564 {
565     std::shared_lock<std::shared_mutex> readLock(mutex_);
566     if (paragraph_ == nullptr) {
567         TEXT_LOGI_LIMIT3_MIN("Failed to get paragraph");
568         return false;
569     }
570     return paragraph_->CanPaintAllText();
571 }
572 
GetDumpInfo() const573 std::string Typography::GetDumpInfo() const
574 {
575     std::shared_lock<std::shared_mutex> readLock(mutex_);
576     if (paragraph_ == nullptr) {
577         return {};
578     }
579     return paragraph_->GetDumpInfo();
580 }
581 
582 } // namespace AdapterTxt
583 } // namespace Rosen
584 } // namespace OHOS
585