• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 #include "core/fxcrt/fx_bidi.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7 
8 namespace {
9 
10 const wchar_t kNeutralChar = 32;   // ' '
11 const wchar_t kLeftChar = 65;      // 'A'
12 const wchar_t kRightChar = 1488;   // 'א'
13 const wchar_t kLeftWeakChar = 46;  // '.'
14 
15 }  // namespace
16 
TEST(fxcrt,BidiCharEmpty)17 TEST(fxcrt, BidiCharEmpty) {
18   CFX_BidiChar bidi;
19   CFX_BidiChar::Segment info;
20 
21   info = bidi.GetSegmentInfo();
22   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, info.direction);
23   EXPECT_EQ(0, info.start);
24   EXPECT_EQ(0, info.count);
25   EXPECT_FALSE(bidi.EndChar());
26 }
27 
TEST(fxcrt,BidiCharLeft)28 TEST(fxcrt, BidiCharLeft) {
29   CFX_BidiChar bidi;
30   CFX_BidiChar::Segment info;
31 
32   EXPECT_TRUE(bidi.AppendChar(kLeftChar));
33   info = bidi.GetSegmentInfo();
34   EXPECT_EQ(0, info.start);
35   EXPECT_EQ(0, info.count);
36 
37   EXPECT_FALSE(bidi.AppendChar(kLeftChar));
38   EXPECT_FALSE(bidi.AppendChar(kLeftChar));
39 
40   info = bidi.GetSegmentInfo();
41   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, info.direction);
42   EXPECT_EQ(0, info.start);
43   EXPECT_EQ(0, info.count);
44 
45   EXPECT_TRUE(bidi.EndChar());
46   info = bidi.GetSegmentInfo();
47   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, info.direction);
48   EXPECT_EQ(0, info.start);
49   EXPECT_EQ(3, info.count);
50 
51   EXPECT_FALSE(bidi.EndChar());
52 }
53 
TEST(fxcrt,BidiCharLeftNeutralRight)54 TEST(fxcrt, BidiCharLeftNeutralRight) {
55   CFX_BidiChar bidi;
56   CFX_BidiChar::Segment info;
57 
58   EXPECT_TRUE(bidi.AppendChar(kLeftChar));
59   info = bidi.GetSegmentInfo();
60   EXPECT_EQ(0, info.start);
61   EXPECT_EQ(0, info.count);
62 
63   EXPECT_FALSE(bidi.AppendChar(kLeftChar));
64   EXPECT_FALSE(bidi.AppendChar(kLeftChar));
65   EXPECT_TRUE(bidi.AppendChar(kNeutralChar));
66   info = bidi.GetSegmentInfo();
67   EXPECT_EQ(0, info.start);
68   EXPECT_EQ(3, info.count);
69 
70   EXPECT_FALSE(bidi.AppendChar(kNeutralChar));
71   EXPECT_FALSE(bidi.AppendChar(kNeutralChar));
72   EXPECT_FALSE(bidi.AppendChar(kNeutralChar));
73   EXPECT_TRUE(bidi.AppendChar(kRightChar));
74   info = bidi.GetSegmentInfo();
75   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, info.direction);
76   EXPECT_EQ(3, info.start);
77   EXPECT_EQ(4, info.count);
78 
79   EXPECT_TRUE(bidi.EndChar());
80   info = bidi.GetSegmentInfo();
81   EXPECT_EQ(CFX_BidiChar::Direction::kRight, info.direction);
82   EXPECT_EQ(7, info.start);
83   EXPECT_EQ(1, info.count);
84 
85   EXPECT_FALSE(bidi.EndChar());
86 }
87 
TEST(fxcrt,BidiCharLeftLeftWeakRight)88 TEST(fxcrt, BidiCharLeftLeftWeakRight) {
89   CFX_BidiChar bidi;
90   CFX_BidiChar::Segment info;
91 
92   EXPECT_TRUE(bidi.AppendChar(kLeftChar));
93   info = bidi.GetSegmentInfo();
94   EXPECT_EQ(0, info.start);
95   EXPECT_EQ(0, info.count);
96 
97   EXPECT_FALSE(bidi.AppendChar(kLeftChar));
98   EXPECT_FALSE(bidi.AppendChar(kLeftChar));
99   EXPECT_TRUE(bidi.AppendChar(kLeftWeakChar));
100   info = bidi.GetSegmentInfo();
101   EXPECT_EQ(0, info.start);
102   EXPECT_EQ(3, info.count);
103 
104   EXPECT_FALSE(bidi.AppendChar(kLeftWeakChar));
105   EXPECT_FALSE(bidi.AppendChar(kLeftWeakChar));
106   EXPECT_FALSE(bidi.AppendChar(kLeftWeakChar));
107   EXPECT_TRUE(bidi.AppendChar(kRightChar));
108   info = bidi.GetSegmentInfo();
109   EXPECT_EQ(CFX_BidiChar::Direction::kLeftWeak, info.direction);
110   EXPECT_EQ(3, info.start);
111   EXPECT_EQ(4, info.count);
112 
113   EXPECT_TRUE(bidi.EndChar());
114   info = bidi.GetSegmentInfo();
115   EXPECT_EQ(CFX_BidiChar::Direction::kRight, info.direction);
116   EXPECT_EQ(7, info.start);
117   EXPECT_EQ(1, info.count);
118 
119   EXPECT_FALSE(bidi.EndChar());
120 }
121 
TEST(fxcrt,BidiCharLeftRightLeft)122 TEST(fxcrt, BidiCharLeftRightLeft) {
123   CFX_BidiChar bidi;
124   CFX_BidiChar::Segment info;
125 
126   EXPECT_TRUE(bidi.AppendChar(kLeftChar));
127   info = bidi.GetSegmentInfo();
128   EXPECT_EQ(0, info.start);
129   EXPECT_EQ(0, info.count);
130 
131   EXPECT_FALSE(bidi.AppendChar(kLeftChar));
132   EXPECT_FALSE(bidi.AppendChar(kLeftChar));
133   EXPECT_TRUE(bidi.AppendChar(kRightChar));
134   info = bidi.GetSegmentInfo();
135   EXPECT_EQ(0, info.start);
136   EXPECT_EQ(3, info.count);
137 
138   EXPECT_FALSE(bidi.AppendChar(kRightChar));
139   EXPECT_FALSE(bidi.AppendChar(kRightChar));
140   EXPECT_FALSE(bidi.AppendChar(kRightChar));
141   EXPECT_TRUE(bidi.AppendChar(kLeftChar));
142   info = bidi.GetSegmentInfo();
143   EXPECT_EQ(CFX_BidiChar::Direction::kRight, info.direction);
144   EXPECT_EQ(3, info.start);
145   EXPECT_EQ(4, info.count);
146 
147   EXPECT_TRUE(bidi.EndChar());
148   info = bidi.GetSegmentInfo();
149   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, info.direction);
150   EXPECT_EQ(7, info.start);
151   EXPECT_EQ(1, info.count);
152 
153   EXPECT_FALSE(bidi.EndChar());
154 }
155 
TEST(fxcrt,BidiStringEmpty)156 TEST(fxcrt, BidiStringEmpty) {
157   CFX_BidiString bidi(L"");
158   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
159   EXPECT_TRUE(bidi.begin() == bidi.end());
160 }
161 
TEST(fxcrt,BidiStringAllNeutral)162 TEST(fxcrt, BidiStringAllNeutral) {
163   {
164     const wchar_t str[] = {kNeutralChar, 0};
165     CFX_BidiString bidi(str);
166     EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
167 
168     auto it = bidi.begin();
169     ASSERT_NE(it, bidi.end());
170     EXPECT_EQ(0, it->start);
171     EXPECT_EQ(1, it->count);
172     EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
173     ++it;
174     EXPECT_EQ(it, bidi.end());
175   }
176   {
177     const wchar_t str[] = {kNeutralChar, kNeutralChar, kNeutralChar, 0};
178     CFX_BidiString bidi(str);
179     EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
180 
181     auto it = bidi.begin();
182     ASSERT_NE(it, bidi.end());
183     EXPECT_EQ(0, it->start);
184     EXPECT_EQ(3, it->count);
185     EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
186     ++it;
187     EXPECT_EQ(it, bidi.end());
188   }
189 }
190 
TEST(fxcrt,BidiStringAllLeft)191 TEST(fxcrt, BidiStringAllLeft) {
192   {
193     const wchar_t str[] = {kLeftChar, 0};
194     CFX_BidiString bidi(str);
195     EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
196 
197     auto it = bidi.begin();
198     ASSERT_NE(it, bidi.end());
199     EXPECT_EQ(0, it->start);
200     EXPECT_EQ(0, it->count);
201     EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
202     ASSERT_NE(it, bidi.end());
203 
204     ++it;
205     EXPECT_EQ(0, it->start);
206     EXPECT_EQ(1, it->count);
207     EXPECT_EQ(CFX_BidiChar::Direction::kLeft, it->direction);
208     ASSERT_NE(it, bidi.end());
209 
210     ++it;
211     EXPECT_EQ(it, bidi.end());
212   }
213   {
214     const wchar_t str[] = {kLeftChar, kLeftChar, kLeftChar, 0};
215     CFX_BidiString bidi(str);
216     EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
217 
218     auto it = bidi.begin();
219     ASSERT_NE(it, bidi.end());
220     EXPECT_EQ(0, it->start);
221     EXPECT_EQ(0, it->count);
222     EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
223     ASSERT_NE(it, bidi.end());
224 
225     ++it;
226     EXPECT_EQ(0, it->start);
227     EXPECT_EQ(3, it->count);
228     EXPECT_EQ(CFX_BidiChar::Direction::kLeft, it->direction);
229     ASSERT_NE(it, bidi.end());
230 
231     ++it;
232     EXPECT_EQ(it, bidi.end());
233   }
234 }
235 
TEST(fxcrt,BidiStringAllLeftWeak)236 TEST(fxcrt, BidiStringAllLeftWeak) {
237   {
238     const wchar_t str[] = {kLeftWeakChar, 0};
239     CFX_BidiString bidi(str);
240     EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
241 
242     auto it = bidi.begin();
243     ASSERT_NE(it, bidi.end());
244     EXPECT_EQ(0, it->start);
245     EXPECT_EQ(0, it->count);
246     EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
247 
248     ++it;
249     ASSERT_NE(it, bidi.end());
250     EXPECT_EQ(0, it->start);
251     EXPECT_EQ(1, it->count);
252     EXPECT_EQ(CFX_BidiChar::Direction::kLeftWeak, it->direction);
253 
254     ++it;
255     EXPECT_EQ(it, bidi.end());
256   }
257   {
258     const wchar_t str[] = {kLeftWeakChar, kLeftWeakChar, kLeftWeakChar, 0};
259     CFX_BidiString bidi(str);
260     EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
261 
262     auto it = bidi.begin();
263     ASSERT_NE(it, bidi.end());
264     EXPECT_EQ(0, it->start);
265     EXPECT_EQ(0, it->count);
266     EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
267 
268     ++it;
269     ASSERT_NE(it, bidi.end());
270     EXPECT_EQ(0, it->start);
271     EXPECT_EQ(3, it->count);
272     EXPECT_EQ(CFX_BidiChar::Direction::kLeftWeak, it->direction);
273 
274     ++it;
275     EXPECT_EQ(it, bidi.end());
276   }
277 }
278 
TEST(fxcrt,BidiStringAllRight)279 TEST(fxcrt, BidiStringAllRight) {
280   {
281     const wchar_t str[] = {kRightChar, 0};
282     CFX_BidiString bidi(str);
283     EXPECT_EQ(CFX_BidiChar::Direction::kRight, bidi.OverallDirection());
284 
285     auto it = bidi.begin();
286     EXPECT_EQ(0, it->start);
287     EXPECT_EQ(1, it->count);
288     EXPECT_EQ(CFX_BidiChar::Direction::kRight, it->direction);
289     ASSERT_NE(it, bidi.end());
290 
291     ++it;
292     ASSERT_NE(it, bidi.end());
293     EXPECT_EQ(0, it->start);
294     EXPECT_EQ(0, it->count);
295     EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
296     ASSERT_NE(it, bidi.end());
297 
298     ++it;
299     EXPECT_EQ(it, bidi.end());
300   }
301   {
302     const wchar_t str[] = {kRightChar, kRightChar, kRightChar, 0};
303     CFX_BidiString bidi(str);
304     EXPECT_EQ(CFX_BidiChar::Direction::kRight, bidi.OverallDirection());
305 
306     auto it = bidi.begin();
307     EXPECT_EQ(0, it->start);
308     EXPECT_EQ(3, it->count);
309     EXPECT_EQ(CFX_BidiChar::Direction::kRight, it->direction);
310     ASSERT_NE(it, bidi.end());
311 
312     ++it;
313     ASSERT_NE(it, bidi.end());
314     EXPECT_EQ(0, it->start);
315     EXPECT_EQ(0, it->count);
316     EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
317     ASSERT_NE(it, bidi.end());
318 
319     ++it;
320     EXPECT_EQ(it, bidi.end());
321   }
322 }
323 
TEST(fxcrt,BidiStringLeftNeutralLeftRight)324 TEST(fxcrt, BidiStringLeftNeutralLeftRight) {
325   const wchar_t str[] = {kLeftChar, kNeutralChar, kLeftChar, kRightChar, 0};
326   CFX_BidiString bidi(str);
327   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
328 
329   auto it = bidi.begin();
330   ASSERT_NE(it, bidi.end());
331   EXPECT_EQ(0, it->start);
332   EXPECT_EQ(0, it->count);
333   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
334   ASSERT_NE(it, bidi.end());
335 
336   ++it;
337   EXPECT_EQ(0, it->start);
338   EXPECT_EQ(1, it->count);
339   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, it->direction);
340   ASSERT_NE(it, bidi.end());
341 
342   ++it;
343   EXPECT_EQ(1, it->start);
344   EXPECT_EQ(1, it->count);
345   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
346   ASSERT_NE(it, bidi.end());
347 
348   ++it;
349   EXPECT_EQ(2, it->start);
350   EXPECT_EQ(1, it->count);
351   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, it->direction);
352   ASSERT_NE(it, bidi.end());
353 
354   ++it;
355   EXPECT_EQ(3, it->start);
356   EXPECT_EQ(1, it->count);
357   EXPECT_EQ(CFX_BidiChar::Direction::kRight, it->direction);
358   ASSERT_NE(it, bidi.end());
359 
360   ++it;
361   EXPECT_EQ(it, bidi.end());
362 }
363 
TEST(fxcrt,BidiStringRightNeutralLeftRight)364 TEST(fxcrt, BidiStringRightNeutralLeftRight) {
365   const wchar_t str[] = {kRightChar, kNeutralChar, kLeftChar, kRightChar, 0};
366   CFX_BidiString bidi(str);
367   EXPECT_EQ(CFX_BidiChar::Direction::kRight, bidi.OverallDirection());
368 
369   auto it = bidi.begin();
370   EXPECT_EQ(3, it->start);
371   EXPECT_EQ(1, it->count);
372   EXPECT_EQ(CFX_BidiChar::Direction::kRight, it->direction);
373   ASSERT_NE(it, bidi.end());
374 
375   ++it;
376   EXPECT_EQ(2, it->start);
377   EXPECT_EQ(1, it->count);
378   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, it->direction);
379   ASSERT_NE(it, bidi.end());
380 
381   ++it;
382   EXPECT_EQ(1, it->start);
383   EXPECT_EQ(1, it->count);
384   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
385   ASSERT_NE(it, bidi.end());
386 
387   ++it;
388   EXPECT_EQ(0, it->start);
389   EXPECT_EQ(1, it->count);
390   EXPECT_EQ(CFX_BidiChar::Direction::kRight, it->direction);
391   ASSERT_NE(it, bidi.end());
392 
393   ++it;
394   ASSERT_NE(it, bidi.end());
395   EXPECT_EQ(0, it->start);
396   EXPECT_EQ(0, it->count);
397   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
398   ASSERT_NE(it, bidi.end());
399 
400   ++it;
401   EXPECT_EQ(it, bidi.end());
402 }
403 
TEST(fxcrt,BidiStringRightLeftWeakLeftRight)404 TEST(fxcrt, BidiStringRightLeftWeakLeftRight) {
405   const wchar_t str[] = {kRightChar, kLeftWeakChar, kLeftChar, kRightChar, 0};
406   CFX_BidiString bidi(str);
407   EXPECT_EQ(CFX_BidiChar::Direction::kRight, bidi.OverallDirection());
408 
409   auto it = bidi.begin();
410   ASSERT_NE(it, bidi.end());
411   EXPECT_EQ(3, it->start);
412   EXPECT_EQ(1, it->count);
413   EXPECT_EQ(CFX_BidiChar::Direction::kRight, it->direction);
414 
415   ++it;
416   ASSERT_NE(it, bidi.end());
417   EXPECT_EQ(2, it->start);
418   EXPECT_EQ(1, it->count);
419   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, it->direction);
420 
421   ++it;
422   ASSERT_NE(it, bidi.end());
423   EXPECT_EQ(1, it->start);
424   EXPECT_EQ(1, it->count);
425   EXPECT_EQ(CFX_BidiChar::Direction::kLeftWeak, it->direction);
426 
427   ++it;
428   ASSERT_NE(it, bidi.end());
429   EXPECT_EQ(0, it->start);
430   EXPECT_EQ(1, it->count);
431   EXPECT_EQ(CFX_BidiChar::Direction::kRight, it->direction);
432 
433   ++it;
434   ASSERT_NE(it, bidi.end());
435   EXPECT_EQ(0, it->start);
436   EXPECT_EQ(0, it->count);
437   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
438 
439   ++it;
440   EXPECT_EQ(it, bidi.end());
441 }
442 
TEST(fxcrt,BidiStringReverse)443 TEST(fxcrt, BidiStringReverse) {
444   const wchar_t str[] = {kLeftChar,     kNeutralChar, kRightChar,
445                          kLeftWeakChar, kLeftChar,    0};
446   CFX_BidiString bidi(str);
447   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, bidi.OverallDirection());
448   bidi.SetOverallDirectionRight();
449 
450   auto it = bidi.begin();
451   ASSERT_NE(it, bidi.end());
452   EXPECT_EQ(4, it->start);
453   EXPECT_EQ(1, it->count);
454   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, it->direction);
455 
456   ++it;
457   ASSERT_NE(it, bidi.end());
458   EXPECT_EQ(3, it->start);
459   EXPECT_EQ(1, it->count);
460   EXPECT_EQ(CFX_BidiChar::Direction::kLeftWeak, it->direction);
461 
462   ++it;
463   ASSERT_NE(it, bidi.end());
464   EXPECT_EQ(2, it->start);
465   EXPECT_EQ(1, it->count);
466   EXPECT_EQ(CFX_BidiChar::Direction::kRight, it->direction);
467 
468   ++it;
469   ASSERT_NE(it, bidi.end());
470   EXPECT_EQ(1, it->start);
471   EXPECT_EQ(1, it->count);
472   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
473 
474   ++it;
475   ASSERT_NE(it, bidi.end());
476   EXPECT_EQ(0, it->start);
477   EXPECT_EQ(1, it->count);
478   EXPECT_EQ(CFX_BidiChar::Direction::kLeft, it->direction);
479 
480   ++it;
481   ASSERT_NE(it, bidi.end());
482   EXPECT_EQ(0, it->start);
483   EXPECT_EQ(0, it->count);
484   EXPECT_EQ(CFX_BidiChar::Direction::kNeutral, it->direction);
485 
486   ++it;
487   EXPECT_EQ(it, bidi.end());
488 }
489