1 // Copyright 2015 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 #include "core/fxcrt/fx_bidi.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7
8 namespace {
9
10 const FX_WCHAR kNeutralChar = 32;
11 const FX_WCHAR kLeftChar = 65;
12 const FX_WCHAR kRightChar = 1424;
13
14 } // namespace
15
TEST(fxcrt,BidiCharEmpty)16 TEST(fxcrt, BidiCharEmpty) {
17 CFX_BidiChar bidi;
18 CFX_BidiChar::Segment info;
19
20 info = bidi.GetSegmentInfo();
21 EXPECT_EQ(CFX_BidiChar::NEUTRAL, info.direction);
22 EXPECT_EQ(0, info.start);
23 EXPECT_EQ(0, info.count);
24 EXPECT_FALSE(bidi.EndChar());
25 }
26
TEST(fxcrt,BidiCharLeft)27 TEST(fxcrt, BidiCharLeft) {
28 CFX_BidiChar bidi;
29 CFX_BidiChar::Segment info;
30
31 EXPECT_TRUE(bidi.AppendChar(kLeftChar));
32 info = bidi.GetSegmentInfo();
33 EXPECT_EQ(0, info.start);
34 EXPECT_EQ(0, info.count);
35
36 EXPECT_FALSE(bidi.AppendChar(kLeftChar));
37 EXPECT_FALSE(bidi.AppendChar(kLeftChar));
38
39 info = bidi.GetSegmentInfo();
40 EXPECT_EQ(CFX_BidiChar::NEUTRAL, info.direction);
41 EXPECT_EQ(0, info.start);
42 EXPECT_EQ(0, info.count);
43
44 EXPECT_TRUE(bidi.EndChar());
45 info = bidi.GetSegmentInfo();
46 EXPECT_EQ(CFX_BidiChar::LEFT, info.direction);
47 EXPECT_EQ(0, info.start);
48 EXPECT_EQ(3, info.count);
49
50 EXPECT_FALSE(bidi.EndChar());
51 }
52
TEST(fxcrt,BidiCharLeftNeutralRight)53 TEST(fxcrt, BidiCharLeftNeutralRight) {
54 CFX_BidiChar bidi;
55 CFX_BidiChar::Segment info;
56
57 EXPECT_TRUE(bidi.AppendChar(kLeftChar));
58 info = bidi.GetSegmentInfo();
59 EXPECT_EQ(0, info.start);
60 EXPECT_EQ(0, info.count);
61
62 EXPECT_FALSE(bidi.AppendChar(kLeftChar));
63 EXPECT_FALSE(bidi.AppendChar(kLeftChar));
64 EXPECT_TRUE(bidi.AppendChar(kNeutralChar));
65 info = bidi.GetSegmentInfo();
66 EXPECT_EQ(0, info.start);
67 EXPECT_EQ(3, info.count);
68
69 EXPECT_FALSE(bidi.AppendChar(kNeutralChar));
70 EXPECT_FALSE(bidi.AppendChar(kNeutralChar));
71 EXPECT_FALSE(bidi.AppendChar(kNeutralChar));
72 EXPECT_TRUE(bidi.AppendChar(kRightChar));
73 info = bidi.GetSegmentInfo();
74 EXPECT_EQ(CFX_BidiChar::NEUTRAL, info.direction);
75 EXPECT_EQ(3, info.start);
76 EXPECT_EQ(4, info.count);
77
78 EXPECT_TRUE(bidi.EndChar());
79 info = bidi.GetSegmentInfo();
80 EXPECT_EQ(CFX_BidiChar::RIGHT, info.direction);
81 EXPECT_EQ(7, info.start);
82 EXPECT_EQ(1, info.count);
83
84 EXPECT_FALSE(bidi.EndChar());
85 }
86
TEST(fxcrt,BidiCharLeftRightLeft)87 TEST(fxcrt, BidiCharLeftRightLeft) {
88 CFX_BidiChar bidi;
89 CFX_BidiChar::Segment info;
90
91 EXPECT_TRUE(bidi.AppendChar(kLeftChar));
92 info = bidi.GetSegmentInfo();
93 EXPECT_EQ(0, info.start);
94 EXPECT_EQ(0, info.count);
95
96 EXPECT_FALSE(bidi.AppendChar(kLeftChar));
97 EXPECT_FALSE(bidi.AppendChar(kLeftChar));
98 EXPECT_TRUE(bidi.AppendChar(kRightChar));
99 info = bidi.GetSegmentInfo();
100 EXPECT_EQ(0, info.start);
101 EXPECT_EQ(3, info.count);
102
103 EXPECT_FALSE(bidi.AppendChar(kRightChar));
104 EXPECT_FALSE(bidi.AppendChar(kRightChar));
105 EXPECT_FALSE(bidi.AppendChar(kRightChar));
106 EXPECT_TRUE(bidi.AppendChar(kLeftChar));
107 info = bidi.GetSegmentInfo();
108 EXPECT_EQ(CFX_BidiChar::RIGHT, info.direction);
109 EXPECT_EQ(3, info.start);
110 EXPECT_EQ(4, info.count);
111
112 EXPECT_TRUE(bidi.EndChar());
113 info = bidi.GetSegmentInfo();
114 EXPECT_EQ(CFX_BidiChar::LEFT, info.direction);
115 EXPECT_EQ(7, info.start);
116 EXPECT_EQ(1, info.count);
117
118 EXPECT_FALSE(bidi.EndChar());
119 }
120
TEST(fxcrt,BidiStringEmpty)121 TEST(fxcrt, BidiStringEmpty) {
122 CFX_BidiString bidi(L"");
123 EXPECT_EQ(CFX_BidiChar::LEFT, bidi.OverallDirection());
124 EXPECT_TRUE(bidi.begin() == bidi.end());
125 }
126
TEST(fxcrt,BidiStringAllNeutral)127 TEST(fxcrt, BidiStringAllNeutral) {
128 {
129 const FX_WCHAR str[] = {kNeutralChar, 0};
130 CFX_BidiString bidi(str);
131 EXPECT_EQ(CFX_BidiChar::LEFT, bidi.OverallDirection());
132
133 auto it = bidi.begin();
134 ASSERT_FALSE(it == bidi.end());
135 EXPECT_EQ(0, it->start);
136 EXPECT_EQ(1, it->count);
137 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
138 ++it;
139 EXPECT_TRUE(it == bidi.end());
140 }
141 {
142 const FX_WCHAR str[] = {kNeutralChar, kNeutralChar, kNeutralChar, 0};
143 CFX_BidiString bidi(str);
144 EXPECT_EQ(CFX_BidiChar::LEFT, bidi.OverallDirection());
145
146 auto it = bidi.begin();
147 ASSERT_FALSE(it == bidi.end());
148 EXPECT_EQ(0, it->start);
149 EXPECT_EQ(3, it->count);
150 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
151 ++it;
152 EXPECT_TRUE(it == bidi.end());
153 }
154 }
155
TEST(fxcrt,BidiStringAllLeft)156 TEST(fxcrt, BidiStringAllLeft) {
157 {
158 const FX_WCHAR str[] = {kLeftChar, 0};
159 CFX_BidiString bidi(str);
160 EXPECT_EQ(CFX_BidiChar::LEFT, bidi.OverallDirection());
161
162 auto it = bidi.begin();
163 ASSERT_FALSE(it == bidi.end());
164 EXPECT_EQ(0, it->start);
165 EXPECT_EQ(0, it->count);
166 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
167 ASSERT_FALSE(it == bidi.end());
168
169 ++it;
170 EXPECT_EQ(0, it->start);
171 EXPECT_EQ(1, it->count);
172 EXPECT_EQ(CFX_BidiChar::LEFT, it->direction);
173 ASSERT_FALSE(it == bidi.end());
174
175 ++it;
176 EXPECT_TRUE(it == bidi.end());
177 }
178 {
179 const FX_WCHAR str[] = {kLeftChar, kLeftChar, kLeftChar, 0};
180 CFX_BidiString bidi(str);
181 EXPECT_EQ(CFX_BidiChar::LEFT, bidi.OverallDirection());
182
183 auto it = bidi.begin();
184 ASSERT_FALSE(it == bidi.end());
185 EXPECT_EQ(0, it->start);
186 EXPECT_EQ(0, it->count);
187 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
188 ASSERT_FALSE(it == bidi.end());
189
190 ++it;
191 EXPECT_EQ(0, it->start);
192 EXPECT_EQ(3, it->count);
193 EXPECT_EQ(CFX_BidiChar::LEFT, it->direction);
194 ASSERT_FALSE(it == bidi.end());
195
196 ++it;
197 EXPECT_TRUE(it == bidi.end());
198 }
199 }
200
TEST(fxcrt,BidiStringAllRight)201 TEST(fxcrt, BidiStringAllRight) {
202 {
203 const FX_WCHAR str[] = {kRightChar, 0};
204 CFX_BidiString bidi(str);
205 EXPECT_EQ(CFX_BidiChar::RIGHT, bidi.OverallDirection());
206
207 auto it = bidi.begin();
208 EXPECT_EQ(0, it->start);
209 EXPECT_EQ(1, it->count);
210 EXPECT_EQ(CFX_BidiChar::RIGHT, it->direction);
211 ASSERT_FALSE(it == bidi.end());
212
213 ++it;
214 ASSERT_FALSE(it == bidi.end());
215 EXPECT_EQ(0, it->start);
216 EXPECT_EQ(0, it->count);
217 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
218 ASSERT_FALSE(it == bidi.end());
219
220 ++it;
221 EXPECT_TRUE(it == bidi.end());
222 }
223 {
224 const FX_WCHAR str[] = {kRightChar, kRightChar, kRightChar, 0};
225 CFX_BidiString bidi(str);
226 EXPECT_EQ(CFX_BidiChar::RIGHT, bidi.OverallDirection());
227
228 auto it = bidi.begin();
229 EXPECT_EQ(0, it->start);
230 EXPECT_EQ(3, it->count);
231 EXPECT_EQ(CFX_BidiChar::RIGHT, it->direction);
232 ASSERT_FALSE(it == bidi.end());
233
234 ++it;
235 ASSERT_FALSE(it == bidi.end());
236 EXPECT_EQ(0, it->start);
237 EXPECT_EQ(0, it->count);
238 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
239 ASSERT_FALSE(it == bidi.end());
240
241 ++it;
242 EXPECT_TRUE(it == bidi.end());
243 }
244 }
245
TEST(fxcrt,BidiStringLeftNeutralLeftRight)246 TEST(fxcrt, BidiStringLeftNeutralLeftRight) {
247 const FX_WCHAR str[] = {kLeftChar, kNeutralChar, kLeftChar, kRightChar, 0};
248 CFX_BidiString bidi(str);
249 EXPECT_EQ(CFX_BidiChar::LEFT, bidi.OverallDirection());
250
251 auto it = bidi.begin();
252 ASSERT_FALSE(it == bidi.end());
253 EXPECT_EQ(0, it->start);
254 EXPECT_EQ(0, it->count);
255 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
256 ASSERT_FALSE(it == bidi.end());
257
258 ++it;
259 EXPECT_EQ(0, it->start);
260 EXPECT_EQ(1, it->count);
261 EXPECT_EQ(CFX_BidiChar::LEFT, it->direction);
262 ASSERT_FALSE(it == bidi.end());
263
264 ++it;
265 EXPECT_EQ(1, it->start);
266 EXPECT_EQ(1, it->count);
267 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
268 ASSERT_FALSE(it == bidi.end());
269
270 ++it;
271 EXPECT_EQ(2, it->start);
272 EXPECT_EQ(1, it->count);
273 EXPECT_EQ(CFX_BidiChar::LEFT, it->direction);
274 ASSERT_FALSE(it == bidi.end());
275
276 ++it;
277 EXPECT_EQ(3, it->start);
278 EXPECT_EQ(1, it->count);
279 EXPECT_EQ(CFX_BidiChar::RIGHT, it->direction);
280 ASSERT_FALSE(it == bidi.end());
281
282 ++it;
283 EXPECT_TRUE(it == bidi.end());
284 }
285
TEST(fxcrt,BidiStringRightNeutralLeftRight)286 TEST(fxcrt, BidiStringRightNeutralLeftRight) {
287 const FX_WCHAR str[] = {kRightChar, kNeutralChar, kLeftChar, kRightChar, 0};
288 CFX_BidiString bidi(str);
289 EXPECT_EQ(CFX_BidiChar::RIGHT, bidi.OverallDirection());
290
291 auto it = bidi.begin();
292 EXPECT_EQ(3, it->start);
293 EXPECT_EQ(1, it->count);
294 EXPECT_EQ(CFX_BidiChar::RIGHT, it->direction);
295 ASSERT_FALSE(it == bidi.end());
296
297 ++it;
298 EXPECT_EQ(2, it->start);
299 EXPECT_EQ(1, it->count);
300 EXPECT_EQ(CFX_BidiChar::LEFT, it->direction);
301 ASSERT_FALSE(it == bidi.end());
302
303 ++it;
304 EXPECT_EQ(1, it->start);
305 EXPECT_EQ(1, it->count);
306 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
307 ASSERT_FALSE(it == bidi.end());
308
309 ++it;
310 EXPECT_EQ(0, it->start);
311 EXPECT_EQ(1, it->count);
312 EXPECT_EQ(CFX_BidiChar::RIGHT, it->direction);
313 ASSERT_FALSE(it == bidi.end());
314
315 ++it;
316 ASSERT_FALSE(it == bidi.end());
317 EXPECT_EQ(0, it->start);
318 EXPECT_EQ(0, it->count);
319 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
320 ASSERT_FALSE(it == bidi.end());
321
322 ++it;
323 EXPECT_TRUE(it == bidi.end());
324 }
325
TEST(fxcrt,BidiStringReverse)326 TEST(fxcrt, BidiStringReverse) {
327 const FX_WCHAR str[] = {kLeftChar, kNeutralChar, kRightChar, kLeftChar, 0};
328 CFX_BidiString bidi(str);
329 EXPECT_EQ(CFX_BidiChar::LEFT, bidi.OverallDirection());
330 bidi.SetOverallDirectionRight();
331
332 auto it = bidi.begin();
333 ASSERT_FALSE(it == bidi.end());
334 EXPECT_EQ(3, it->start);
335 EXPECT_EQ(1, it->count);
336 EXPECT_EQ(CFX_BidiChar::LEFT, it->direction);
337
338 ++it;
339 ASSERT_FALSE(it == bidi.end());
340 EXPECT_EQ(2, it->start);
341 EXPECT_EQ(1, it->count);
342 EXPECT_EQ(CFX_BidiChar::RIGHT, it->direction);
343 ASSERT_FALSE(it == bidi.end());
344
345 ++it;
346 ASSERT_FALSE(it == bidi.end());
347 EXPECT_EQ(1, it->start);
348 EXPECT_EQ(1, it->count);
349 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
350
351 ++it;
352 ASSERT_FALSE(it == bidi.end());
353 EXPECT_EQ(0, it->start);
354 EXPECT_EQ(1, it->count);
355 EXPECT_EQ(CFX_BidiChar::LEFT, it->direction);
356
357 ++it;
358 ASSERT_FALSE(it == bidi.end());
359 EXPECT_EQ(0, it->start);
360 EXPECT_EQ(0, it->count);
361 EXPECT_EQ(CFX_BidiChar::NEUTRAL, it->direction);
362
363 ++it;
364 EXPECT_TRUE(it == bidi.end());
365 }
366