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