1 // Copyright 2017 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/fgas/layout/cfx_char.h"
8
9 #include <algorithm>
10
11 #include "core/fxcrt/fx_extension.h"
12
13 namespace {
14
15 #ifndef NDEBUG
16 constexpr int32_t kBidiMaxLevel = 61;
17 #endif // NDEBUG
18
19 #undef PACK_NIBBLES
20 #define PACK_NIBBLES(hi, lo) \
21 ((static_cast<uint32_t>(hi) << 4) + static_cast<uint32_t>(lo))
22
23 enum FX_BIDIWEAKSTATE : uint8_t {
24 FX_BWSxa = 0,
25 FX_BWSxr,
26 FX_BWSxl,
27 FX_BWSao,
28 FX_BWSro,
29 FX_BWSlo,
30 FX_BWSrt,
31 FX_BWSlt,
32 FX_BWScn,
33 FX_BWSra,
34 FX_BWSre,
35 FX_BWSla,
36 FX_BWSle,
37 FX_BWSac,
38 FX_BWSrc,
39 FX_BWSrs,
40 FX_BWSlc,
41 FX_BWSls,
42 FX_BWSret,
43 FX_BWSlet
44 };
45
46 // NOTE: Range of FX_BIDICLASS prevents encoding all possible values in this
47 // manner, but the ones used manage to fit. Except that I suspect that 0xF
48 // was intended to be used as a sentinel, even though it also means kRLE.
49 // TODO(tsepez): pick a better representation.
50 enum FX_BIDIWEAKACTION : uint16_t {
51 FX_BWAIX = 0x100,
52 FX_BWAXX = 0x0F,
53 FX_BWAxxx = 0xFF,
54 FX_BWAxIx = 0x100 + FX_BWAxxx,
55 FX_BWAxxN = PACK_NIBBLES(0x0F, FX_BIDICLASS::kON),
56 FX_BWAxxE = PACK_NIBBLES(0x0F, FX_BIDICLASS::kEN),
57 FX_BWAxxA = PACK_NIBBLES(0x0F, FX_BIDICLASS::kAN),
58 FX_BWAxxR = PACK_NIBBLES(0x0F, FX_BIDICLASS::kR),
59 FX_BWAxxL = PACK_NIBBLES(0x0F, FX_BIDICLASS::kL),
60 FX_BWANxx = PACK_NIBBLES(FX_BIDICLASS::kON, 0x0F),
61 FX_BWAAxx = PACK_NIBBLES(FX_BIDICLASS::kAN, 0x0F),
62 FX_BWAExE = PACK_NIBBLES(FX_BIDICLASS::kEN, FX_BIDICLASS::kEN),
63 FX_BWANIx = 0x100 + PACK_NIBBLES(FX_BIDICLASS::kON, 0x0F),
64 FX_BWANxN = PACK_NIBBLES(FX_BIDICLASS::kON, FX_BIDICLASS::kON),
65 FX_BWANxR = PACK_NIBBLES(FX_BIDICLASS::kON, FX_BIDICLASS::kR),
66 FX_BWANxE = PACK_NIBBLES(FX_BIDICLASS::kON, FX_BIDICLASS::kEN),
67 FX_BWAAxA = PACK_NIBBLES(FX_BIDICLASS::kAN, FX_BIDICLASS::kAN),
68 FX_BWANxL = PACK_NIBBLES(FX_BIDICLASS::kON, FX_BIDICLASS::kL),
69 FX_BWALxL = PACK_NIBBLES(FX_BIDICLASS::kL, FX_BIDICLASS::kL),
70 FX_BWAxIL = 0x100 + PACK_NIBBLES(0x0F, FX_BIDICLASS::kL),
71 FX_BWAAxR = PACK_NIBBLES(FX_BIDICLASS::kAN, FX_BIDICLASS::kR),
72 FX_BWALxx = PACK_NIBBLES(FX_BIDICLASS::kL, 0x0F),
73 };
74
75 enum FX_BIDINEUTRALSTATE : uint8_t {
76 FX_BNSr = 0,
77 FX_BNSl,
78 FX_BNSrn,
79 FX_BNSln,
80 FX_BNSa,
81 FX_BNSna
82 };
83
84 enum FX_BIDINEUTRALACTION : uint16_t {
85 // For placeholders in table.
86 FX_BNAZero = 0,
87
88 // Other values.
89 FX_BNAnL = PACK_NIBBLES(0, FX_BIDICLASS::kL),
90 FX_BNAEn = PACK_NIBBLES(FX_BIDICLASS::kAN, 0),
91 FX_BNARn = PACK_NIBBLES(FX_BIDICLASS::kR, 0),
92 FX_BNALn = PACK_NIBBLES(FX_BIDICLASS::kL, 0),
93 FX_BNAIn = FX_BWAIX,
94 FX_BNALnL = PACK_NIBBLES(FX_BIDICLASS::kL, FX_BIDICLASS::kL),
95 };
96 #undef PACK_NIBBLES
97
98 const FX_BIDICLASS kNTypes[] = {
99 FX_BIDICLASS::kN, FX_BIDICLASS::kL, FX_BIDICLASS::kR,
100 FX_BIDICLASS::kAN, FX_BIDICLASS::kEN, FX_BIDICLASS::kAL,
101 FX_BIDICLASS::kNSM, FX_BIDICLASS::kCS, FX_BIDICLASS::kES,
102 FX_BIDICLASS::kET, FX_BIDICLASS::kBN, FX_BIDICLASS::kBN,
103 FX_BIDICLASS::kN, FX_BIDICLASS::kB, FX_BIDICLASS::kRLO,
104 FX_BIDICLASS::kRLE, FX_BIDICLASS::kLRO, FX_BIDICLASS::kLRE,
105 FX_BIDICLASS::kPDF, FX_BIDICLASS::kON,
106 };
107
108 const FX_BIDIWEAKSTATE kWeakStates[20][10] = {
109 {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSxa,
110 FX_BWSao, FX_BWSao, FX_BWSao},
111 {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSxr,
112 FX_BWSro, FX_BWSro, FX_BWSrt},
113 {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSxl,
114 FX_BWSlo, FX_BWSlo, FX_BWSlt},
115 {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSao,
116 FX_BWSao, FX_BWSao, FX_BWSao},
117 {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
118 FX_BWSro, FX_BWSro, FX_BWSrt},
119 {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
120 FX_BWSlo, FX_BWSlo, FX_BWSlt},
121 {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSrt,
122 FX_BWSro, FX_BWSro, FX_BWSrt},
123 {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlt,
124 FX_BWSlo, FX_BWSlo, FX_BWSlt},
125 {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWScn,
126 FX_BWSac, FX_BWSao, FX_BWSao},
127 {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSra,
128 FX_BWSrc, FX_BWSro, FX_BWSrt},
129 {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSre,
130 FX_BWSrs, FX_BWSrs, FX_BWSret},
131 {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSla,
132 FX_BWSlc, FX_BWSlo, FX_BWSlt},
133 {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSle,
134 FX_BWSls, FX_BWSls, FX_BWSlet},
135 {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSao,
136 FX_BWSao, FX_BWSao, FX_BWSao},
137 {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
138 FX_BWSro, FX_BWSro, FX_BWSrt},
139 {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro,
140 FX_BWSro, FX_BWSro, FX_BWSrt},
141 {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
142 FX_BWSlo, FX_BWSlo, FX_BWSlt},
143 {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo,
144 FX_BWSlo, FX_BWSlo, FX_BWSlt},
145 {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSret,
146 FX_BWSro, FX_BWSro, FX_BWSret},
147 {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlet,
148 FX_BWSlo, FX_BWSlo, FX_BWSlet},
149 };
150
151 const FX_BIDIWEAKACTION kWeakActions[20][10] = {
152 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
153 FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN},
154 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
155 FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
156 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
157 FX_BWAxxL, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
158 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
159 FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN},
160 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
161 FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
162 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
163 FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
164 {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAExE, FX_BWANxR,
165 FX_BWAxIx, FX_BWANxN, FX_BWANxN, FX_BWAxIx},
166 {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWALxL, FX_BWANxR,
167 FX_BWAxIx, FX_BWANxN, FX_BWANxN, FX_BWAxIx},
168 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR,
169 FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxxN},
170 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
171 FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxIx},
172 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
173 FX_BWAxxE, FX_BWAxIx, FX_BWAxIx, FX_BWAxxE},
174 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
175 FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxIx},
176 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
177 FX_BWAxxL, FX_BWAxIx, FX_BWAxIx, FX_BWAxxL},
178 {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWAAxA, FX_BWANxR,
179 FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANxN},
180 {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWANxE, FX_BWANxR,
181 FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
182 {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAExE, FX_BWANxR,
183 FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
184 {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWANxL, FX_BWANxR,
185 FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
186 {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWALxL, FX_BWANxR,
187 FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
188 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR,
189 FX_BWAxxE, FX_BWAxxN, FX_BWAxxN, FX_BWAxxE},
190 {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR,
191 FX_BWAxxL, FX_BWAxxN, FX_BWAxxN, FX_BWAxxL},
192 };
193
194 const FX_BIDINEUTRALSTATE kNeutralStates[6][5] = {
195 {FX_BNSrn, FX_BNSl, FX_BNSr, FX_BNSr, FX_BNSr},
196 {FX_BNSln, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
197 {FX_BNSrn, FX_BNSl, FX_BNSr, FX_BNSr, FX_BNSr},
198 {FX_BNSln, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
199 {FX_BNSna, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
200 {FX_BNSna, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
201 };
202
203 const FX_BIDINEUTRALACTION kNeutralActions[6][5] = {
204 {FX_BNAIn, FX_BNAZero, FX_BNAZero, FX_BNAZero, FX_BNAZero},
205 {FX_BNAIn, FX_BNAZero, FX_BNAZero, FX_BNAZero, FX_BNAnL},
206 {FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNARn},
207 {FX_BNAIn, FX_BNALn, FX_BNAEn, FX_BNAEn, FX_BNALnL},
208 {FX_BNAIn, FX_BNAZero, FX_BNAZero, FX_BNAZero, FX_BNAnL},
209 {FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNAEn},
210 };
211
212 const uint8_t kAddLevel[2][4] = {
213 {0, 1, 2, 2},
214 {1, 0, 1, 1},
215 };
216
Direction(int32_t val)217 FX_BIDICLASS Direction(int32_t val) {
218 return FX_IsOdd(val) ? FX_BIDICLASS::kR : FX_BIDICLASS::kL;
219 }
220
GetDeferredType(int32_t val)221 FX_BIDICLASS GetDeferredType(int32_t val) {
222 return static_cast<FX_BIDICLASS>((val >> 4) & 0x0F);
223 }
224
GetResolvedType(int32_t val)225 FX_BIDICLASS GetResolvedType(int32_t val) {
226 return static_cast<FX_BIDICLASS>(val & 0x0F);
227 }
228
GetDeferredNeutrals(int32_t iAction,int32_t iLevel)229 FX_BIDICLASS GetDeferredNeutrals(int32_t iAction, int32_t iLevel) {
230 FX_BIDICLASS eClass = GetDeferredType(iAction);
231 return eClass == FX_BIDICLASS::kAN ? Direction(iLevel) : eClass;
232 }
233
GetResolvedNeutrals(int32_t iAction)234 FX_BIDICLASS GetResolvedNeutrals(int32_t iAction) {
235 return GetResolvedType(iAction);
236 }
237
GetWeakState(FX_BIDIWEAKSTATE eState,FX_BIDICLASS eClass)238 FX_BIDIWEAKSTATE GetWeakState(FX_BIDIWEAKSTATE eState, FX_BIDICLASS eClass) {
239 ASSERT(static_cast<size_t>(eState) < FX_ArraySize(kWeakStates));
240 ASSERT(static_cast<size_t>(eClass) < FX_ArraySize(kWeakStates[0]));
241 return kWeakStates[static_cast<size_t>(eState)][static_cast<size_t>(eClass)];
242 }
243
GetWeakAction(FX_BIDIWEAKSTATE eState,FX_BIDICLASS eClass)244 FX_BIDIWEAKACTION GetWeakAction(FX_BIDIWEAKSTATE eState, FX_BIDICLASS eClass) {
245 ASSERT(static_cast<size_t>(eState) < FX_ArraySize(kWeakActions));
246 ASSERT(static_cast<size_t>(eClass) < FX_ArraySize(kWeakActions[0]));
247 return kWeakActions[static_cast<size_t>(eState)][static_cast<size_t>(eClass)];
248 }
249
GetNeutralState(FX_BIDINEUTRALSTATE eState,FX_BIDICLASS eClass)250 FX_BIDINEUTRALSTATE GetNeutralState(FX_BIDINEUTRALSTATE eState,
251 FX_BIDICLASS eClass) {
252 ASSERT(static_cast<size_t>(eState) < FX_ArraySize(kNeutralStates));
253 ASSERT(static_cast<size_t>(eClass) < FX_ArraySize(kNeutralStates[0]));
254 return kNeutralStates[static_cast<size_t>(eState)]
255 [static_cast<size_t>(eClass)];
256 }
257
GetNeutralAction(FX_BIDINEUTRALSTATE eState,FX_BIDICLASS eClass)258 FX_BIDINEUTRALACTION GetNeutralAction(FX_BIDINEUTRALSTATE eState,
259 FX_BIDICLASS eClass) {
260 ASSERT(static_cast<size_t>(eState) < FX_ArraySize(kNeutralActions));
261 ASSERT(static_cast<size_t>(eClass) < FX_ArraySize(kNeutralActions[0]));
262 return kNeutralActions[static_cast<size_t>(eState)]
263 [static_cast<size_t>(eClass)];
264 }
265
ReverseString(std::vector<CFX_Char> * chars,size_t iStart,size_t iCount)266 void ReverseString(std::vector<CFX_Char>* chars, size_t iStart, size_t iCount) {
267 ASSERT(pdfium::IndexInBounds(*chars, iStart));
268 ASSERT(iStart + iCount <= chars->size());
269
270 std::reverse(chars->begin() + iStart, chars->begin() + iStart + iCount);
271 }
272
SetDeferredRunClass(std::vector<CFX_Char> * chars,size_t iStart,size_t iCount,FX_BIDICLASS eValue)273 void SetDeferredRunClass(std::vector<CFX_Char>* chars,
274 size_t iStart,
275 size_t iCount,
276 FX_BIDICLASS eValue) {
277 ASSERT(iStart <= chars->size());
278 ASSERT(iStart >= iCount);
279
280 size_t iLast = iStart - iCount;
281 for (size_t i = iStart; i > iLast; --i)
282 (*chars)[i - 1].m_iBidiClass = eValue;
283 }
284
SetDeferredRunLevel(std::vector<CFX_Char> * chars,size_t iStart,size_t iCount,int32_t iValue)285 void SetDeferredRunLevel(std::vector<CFX_Char>* chars,
286 size_t iStart,
287 size_t iCount,
288 int32_t iValue) {
289 ASSERT(iStart <= chars->size());
290 ASSERT(iStart >= iCount);
291
292 size_t iLast = iStart - iCount;
293 for (size_t i = iStart; i > iLast; --i)
294 (*chars)[i - 1].m_iBidiLevel = static_cast<int16_t>(iValue);
295 }
296
Classify(std::vector<CFX_Char> * chars,size_t iCount)297 void Classify(std::vector<CFX_Char>* chars, size_t iCount) {
298 for (size_t i = 0; i < iCount; ++i) {
299 CFX_Char& cur = (*chars)[i];
300 cur.m_iBidiClass = FX_GetBidiClass(cur.char_code());
301 }
302 }
303
ClassifyWithTransform(std::vector<CFX_Char> * chars,size_t iCount)304 void ClassifyWithTransform(std::vector<CFX_Char>* chars, size_t iCount) {
305 for (size_t i = 0; i < iCount; ++i) {
306 CFX_Char& cur = (*chars)[i];
307 cur.m_iBidiClass =
308 kNTypes[static_cast<size_t>(FX_GetBidiClass(cur.char_code()))];
309 }
310 }
311
ResolveExplicit(std::vector<CFX_Char> * chars,size_t iCount)312 void ResolveExplicit(std::vector<CFX_Char>* chars, size_t iCount) {
313 for (size_t i = 0; i < iCount; ++i)
314 (*chars)[i].m_iBidiLevel = 0;
315 }
316
ResolveWeak(std::vector<CFX_Char> * chars,size_t iCount)317 void ResolveWeak(std::vector<CFX_Char>* chars, size_t iCount) {
318 if (iCount <= 1)
319 return;
320 --iCount;
321
322 int32_t iLevelCur = 0;
323 size_t iNum = 0;
324 FX_BIDIWEAKSTATE eState = FX_BWSxl;
325 FX_BIDICLASS eClsCur;
326 FX_BIDICLASS eClsRun;
327 FX_BIDICLASS eClsNew;
328 size_t i = 0;
329 for (; i <= iCount; ++i) {
330 CFX_Char* pTC = &(*chars)[i];
331 eClsCur = pTC->m_iBidiClass;
332 if (eClsCur == FX_BIDICLASS::kBN) {
333 pTC->m_iBidiLevel = (int16_t)iLevelCur;
334 if (i == iCount && iLevelCur != 0) {
335 eClsCur = Direction(iLevelCur);
336 pTC->m_iBidiClass = eClsCur;
337 } else if (i < iCount) {
338 CFX_Char* pTCNext = &(*chars)[i + 1];
339 int32_t iLevelNext, iLevelNew;
340 eClsNew = pTCNext->m_iBidiClass;
341 iLevelNext = pTCNext->m_iBidiLevel;
342 if (eClsNew != FX_BIDICLASS::kBN && iLevelCur != iLevelNext) {
343 iLevelNew = std::max(iLevelNext, iLevelCur);
344 pTC->m_iBidiLevel = static_cast<int16_t>(iLevelNew);
345 eClsCur = Direction(iLevelNew);
346 pTC->m_iBidiClass = eClsCur;
347 iLevelCur = iLevelNext;
348 } else {
349 if (iNum > 0)
350 ++iNum;
351 continue;
352 }
353 } else {
354 if (iNum > 0)
355 ++iNum;
356 continue;
357 }
358 }
359 if (eClsCur > FX_BIDICLASS::kBN)
360 continue;
361
362 FX_BIDIWEAKACTION eAction = GetWeakAction(eState, eClsCur);
363 eClsRun = GetDeferredType(eAction);
364 if (eClsRun != static_cast<FX_BIDICLASS>(0xF) && iNum > 0) {
365 SetDeferredRunClass(chars, i, iNum, eClsRun);
366 iNum = 0;
367 }
368 eClsNew = GetResolvedType(eAction);
369 if (eClsNew != static_cast<FX_BIDICLASS>(0xF))
370 pTC->m_iBidiClass = eClsNew;
371 if (FX_BWAIX & eAction)
372 ++iNum;
373
374 eState = GetWeakState(eState, eClsCur);
375 }
376 if (iNum == 0)
377 return;
378
379 eClsCur = Direction(0);
380 eClsRun = GetDeferredType(GetWeakAction(eState, eClsCur));
381 if (eClsRun != static_cast<FX_BIDICLASS>(0xF))
382 SetDeferredRunClass(chars, i, iNum, eClsRun);
383 }
384
ResolveNeutrals(std::vector<CFX_Char> * chars,size_t iCount)385 void ResolveNeutrals(std::vector<CFX_Char>* chars, size_t iCount) {
386 if (iCount <= 1)
387 return;
388 --iCount;
389
390 CFX_Char* pTC;
391 int32_t iLevel = 0;
392 size_t i = 0;
393 size_t iNum = 0;
394 FX_BIDINEUTRALSTATE eState = FX_BNSl;
395 FX_BIDICLASS eClsCur;
396 FX_BIDICLASS eClsRun;
397 FX_BIDICLASS eClsNew;
398 for (; i <= iCount; ++i) {
399 pTC = &(*chars)[i];
400 eClsCur = pTC->m_iBidiClass;
401 if (eClsCur == FX_BIDICLASS::kBN) {
402 if (iNum)
403 ++iNum;
404 continue;
405 }
406 if (eClsCur >= FX_BIDICLASS::kAL)
407 continue;
408
409 FX_BIDINEUTRALACTION eAction = GetNeutralAction(eState, eClsCur);
410 eClsRun = GetDeferredNeutrals(eAction, iLevel);
411 if (eClsRun != FX_BIDICLASS::kN && iNum > 0) {
412 SetDeferredRunClass(chars, i, iNum, eClsRun);
413 iNum = 0;
414 }
415
416 eClsNew = GetResolvedNeutrals(eAction);
417 if (eClsNew != FX_BIDICLASS::kN)
418 pTC->m_iBidiClass = eClsNew;
419 if (FX_BNAIn & eAction)
420 ++iNum;
421
422 eState = GetNeutralState(eState, eClsCur);
423 iLevel = pTC->m_iBidiLevel;
424 }
425 if (iNum == 0)
426 return;
427
428 eClsCur = Direction(iLevel);
429 eClsRun = GetDeferredNeutrals(GetNeutralAction(eState, eClsCur), iLevel);
430 if (eClsRun != FX_BIDICLASS::kN)
431 SetDeferredRunClass(chars, i, iNum, eClsRun);
432 }
433
ResolveImplicit(std::vector<CFX_Char> * chars,size_t iCount)434 void ResolveImplicit(std::vector<CFX_Char>* chars, size_t iCount) {
435 for (size_t i = 0; i < iCount; ++i) {
436 FX_BIDICLASS eCls = (*chars)[i].m_iBidiClass;
437 if (eCls == FX_BIDICLASS::kBN || eCls <= FX_BIDICLASS::kON ||
438 eCls >= FX_BIDICLASS::kAL) {
439 continue;
440 }
441 (*chars)[i].m_iBidiLevel += kAddLevel[FX_IsOdd((*chars)[i].m_iBidiLevel)]
442 [static_cast<size_t>(eCls) - 1];
443 }
444 }
445
ResolveWhitespace(std::vector<CFX_Char> * chars,size_t iCount)446 void ResolveWhitespace(std::vector<CFX_Char>* chars, size_t iCount) {
447 if (iCount <= 1)
448 return;
449 iCount--;
450
451 int32_t iLevel = 0;
452 size_t i = 0;
453 size_t iNum = 0;
454 for (; i <= iCount; ++i) {
455 switch (static_cast<FX_BIDICLASS>((*chars)[i].m_iBidiClass)) {
456 case FX_BIDICLASS::kWS:
457 ++iNum;
458 break;
459 case FX_BIDICLASS::kRLE:
460 case FX_BIDICLASS::kLRE:
461 case FX_BIDICLASS::kLRO:
462 case FX_BIDICLASS::kRLO:
463 case FX_BIDICLASS::kPDF:
464 case FX_BIDICLASS::kBN:
465 (*chars)[i].m_iBidiLevel = static_cast<int16_t>(iLevel);
466 ++iNum;
467 break;
468 case FX_BIDICLASS::kS:
469 case FX_BIDICLASS::kB:
470 if (iNum > 0)
471 SetDeferredRunLevel(chars, i, iNum, 0);
472
473 (*chars)[i].m_iBidiLevel = 0;
474 iNum = 0;
475 break;
476 default:
477 iNum = 0;
478 break;
479 }
480 iLevel = (*chars)[i].m_iBidiLevel;
481 }
482 if (iNum > 0)
483 SetDeferredRunLevel(chars, i, iNum, 0);
484 }
485
ReorderLevel(std::vector<CFX_Char> * chars,size_t iCount,int32_t iBaseLevel,size_t iStart,bool bReverse)486 size_t ReorderLevel(std::vector<CFX_Char>* chars,
487 size_t iCount,
488 int32_t iBaseLevel,
489 size_t iStart,
490 bool bReverse) {
491 ASSERT(iBaseLevel >= 0);
492 ASSERT(iBaseLevel <= kBidiMaxLevel);
493 ASSERT(iStart < iCount);
494
495 if (iCount < 1)
496 return 0;
497
498 bReverse = bReverse || FX_IsOdd(iBaseLevel);
499 size_t i = iStart;
500 for (; i < iCount; ++i) {
501 int32_t iLevel = (*chars)[i].m_iBidiLevel;
502 if (iLevel == iBaseLevel)
503 continue;
504 if (iLevel < iBaseLevel)
505 break;
506
507 i += ReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
508 }
509
510 size_t iNum = i - iStart;
511 if (bReverse && iNum > 1)
512 ReverseString(chars, iStart, iNum);
513
514 return iNum;
515 }
516
Reorder(std::vector<CFX_Char> * chars,size_t iCount)517 void Reorder(std::vector<CFX_Char>* chars, size_t iCount) {
518 for (size_t i = 0; i < iCount;)
519 i += ReorderLevel(chars, iCount, 0, i, false);
520 }
521
Position(std::vector<CFX_Char> * chars,size_t iCount)522 void Position(std::vector<CFX_Char>* chars, size_t iCount) {
523 for (size_t i = 0; i < iCount; ++i) {
524 if ((*chars)[i].m_iBidiPos > iCount)
525 continue;
526
527 (*chars)[(*chars)[i].m_iBidiPos].m_iBidiOrder = i;
528 }
529 }
530
531 } // namespace
532
533 // static
BidiLine(std::vector<CFX_Char> * chars,size_t iCount)534 void CFX_Char::BidiLine(std::vector<CFX_Char>* chars, size_t iCount) {
535 ASSERT(iCount <= chars->size());
536 if (iCount < 2)
537 return;
538
539 ClassifyWithTransform(chars, iCount);
540 ResolveExplicit(chars, iCount);
541 ResolveWeak(chars, iCount);
542 ResolveNeutrals(chars, iCount);
543 ResolveImplicit(chars, iCount);
544 Classify(chars, iCount);
545 ResolveWhitespace(chars, iCount);
546 Reorder(chars, iCount);
547 Position(chars, iCount);
548 }
549
CFX_Char(uint16_t wCharCode)550 CFX_Char::CFX_Char(uint16_t wCharCode) : CFX_Char(wCharCode, 100, 100) {}
551
CFX_Char(uint16_t wCharCode,int32_t iHorizontalScale,int32_t iVerticalScale)552 CFX_Char::CFX_Char(uint16_t wCharCode,
553 int32_t iHorizontalScale,
554 int32_t iVerticalScale)
555 : m_wCharCode(wCharCode),
556 m_iHorizontalScale(iHorizontalScale),
557 m_iVerticalScale(iVerticalScale) {}
558
559 CFX_Char::CFX_Char(const CFX_Char& other) = default;
560
561 CFX_Char::~CFX_Char() = default;
562
GetCharType() const563 FX_CHARTYPE CFX_Char::GetCharType() const {
564 return FX_GetCharType(m_wCharCode);
565 }
566