• 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 "text_reverser.h"
17 
18 #include "texgine/utils/exlog.h"
19 #ifdef LOGGER_ENABLE_SCOPE
20 #include "texgine/utils/trace.h"
21 #endif
22 
23 namespace OHOS {
24 namespace Rosen {
25 namespace TextEngine {
ReverseRTLText(std::vector<VariantSpan> & lineSpans)26 void TextReverser::ReverseRTLText(std::vector<VariantSpan> &lineSpans)
27 {
28 #ifdef LOGGER_ENABLE_SCOPE
29     ScopedTrace scope("Shaper::ReverseRTLText");
30 #endif
31     LOGSCOPED(sl, LOGEX_FUNC_LINE_DEBUG(), "ReverseRTLText");
32     const auto &endit = lineSpans.end();
33     auto rtlSpansBeginIt = endit;
34     auto rtlSpansEndIt = endit;
35     bool rtl = false;
36     for (auto it = lineSpans.begin(); it != lineSpans.end(); it++) {
37         auto ts = it->TryToTextSpan();
38         if (ts != nullptr) {
39             rtl = ts->IsRTL();
40         }
41 
42         if (rtl) {
43             rtlSpansBeginIt = rtlSpansBeginIt == endit ? it : rtlSpansBeginIt;
44             rtlSpansEndIt = it;
45             LOGCEX_DEBUG() << "is rtl";
46             continue;
47         } else {
48             LOGCEX_DEBUG() << "no rtl";
49         }
50 
51         if (rtlSpansBeginIt == endit) {
52             continue;
53         }
54 
55         rtlSpansEndIt++;
56         LOGSCOPED(sl, LOGEX_FUNC_LINE_DEBUG(), "reverse");
57         for (auto i = rtlSpansBeginIt; i != rtlSpansEndIt; i++) {
58             i->Dump();
59         }
60         std::reverse(rtlSpansBeginIt, rtlSpansEndIt);
61         rtlSpansBeginIt = endit;
62         rtlSpansEndIt = endit;
63     }
64 
65     if (rtlSpansBeginIt != endit) {
66         rtlSpansEndIt++;
67         LOGSCOPED(sl, LOGEX_FUNC_LINE_DEBUG(), "reverse");
68         for (auto it = rtlSpansBeginIt; it != rtlSpansEndIt; it++) {
69             it->Dump();
70         }
71         std::reverse(rtlSpansBeginIt, rtlSpansEndIt);
72     }
73 }
74 
ReverseConDirectionText(std::vector<VariantSpan> & lineSpans,int begin,int end)75 void TextReverser::ReverseConDirectionText(std::vector<VariantSpan> &lineSpans, int begin, int end)
76 {
77     while (begin < end) {
78         if (lineSpans[begin].GetVisibleWidth() == 0) {
79             begin++;
80         }
81 
82         if (lineSpans[end].GetVisibleWidth() == 0) {
83             end--;
84         }
85 
86         if (begin >= end) {
87             break;
88         }
89 
90         auto temp = lineSpans[begin];
91         lineSpans[begin] = lineSpans[end];
92         lineSpans[end] = temp;
93         begin++;
94         end--;
95     }
96 }
97 
ProcessTypoDirection(std::vector<VariantSpan> & lineSpans,const TextDirection dir)98 void TextReverser::ProcessTypoDirection(std::vector<VariantSpan> &lineSpans, const TextDirection dir)
99 {
100 #ifdef LOGGER_ENABLE_SCOPE
101     ScopedTrace scope("ProcessTypoDirection");
102 #endif
103     LOGSCOPED(sl, LOGEX_FUNC_LINE_DEBUG(), "ProcessTypoDirection");
104     if (dir == TextDirection::LTR) {
105         return;
106     }
107 
108     bool isConDirection = false;
109     int index = 0;
110     ReverseConDirectionText(lineSpans, 0, lineSpans.size() - 1);
111 
112     for (auto i = 0; i < static_cast<int>(lineSpans.size()) - 1; i++) {
113         if (lineSpans[i].GetVisibleWidth() == 0 || lineSpans[i + 1].GetVisibleWidth() == 0 ||
114             lineSpans[i].IsRTL() == lineSpans[i + 1].IsRTL()) {
115             isConDirection = true;
116             continue;
117         }
118 
119         if (isConDirection == true) {
120             ReverseConDirectionText(lineSpans, index, i);
121             index = i + 1;
122             isConDirection = false;
123         } else {
124             index++;
125         }
126     }
127 
128     if (isConDirection) {
129         ReverseConDirectionText(lineSpans, index, lineSpans.size() - 1);
130     }
131 }
132 } // namespace TextEngine
133 } // namespace Rosen
134 } // namespace OHOS
135