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