1 // Copyright 2017 The Chromium 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 "third_party/blink/renderer/platform/text/writing_mode_utils.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
9
10 namespace blink {
11
12 namespace {
13
14 enum { kTop, kRight, kBottom, kLeft };
15
16 template <typename PhysicalToLogicalConverter>
CheckLegacyLogicalDirections(const PhysicalToLogicalConverter & converter)17 void CheckLegacyLogicalDirections(const PhysicalToLogicalConverter& converter) {
18 EXPECT_EQ(converter.InlineStart(), converter.Start());
19 EXPECT_EQ(converter.InlineEnd(), converter.End());
20 EXPECT_EQ(converter.BlockStart(), converter.Before());
21 EXPECT_EQ(converter.BlockEnd(), converter.After());
22 }
23
TEST(WritingModeUtilsTest,PhysicalToLogicalHorizontalLtr)24 TEST(WritingModeUtilsTest, PhysicalToLogicalHorizontalLtr) {
25 PhysicalToLogical<int> converter(
26 {WritingMode::kHorizontalTb, TextDirection::kLtr}, kTop, kRight, kBottom,
27 kLeft);
28 EXPECT_EQ(kLeft, converter.InlineStart());
29 EXPECT_EQ(kRight, converter.InlineEnd());
30 EXPECT_EQ(kTop, converter.BlockStart());
31 EXPECT_EQ(kBottom, converter.BlockEnd());
32 EXPECT_EQ(kLeft, converter.LineLeft());
33 EXPECT_EQ(kRight, converter.LineRight());
34 EXPECT_EQ(kTop, converter.Over());
35 EXPECT_EQ(kBottom, converter.Under());
36 CheckLegacyLogicalDirections(converter);
37 }
38
TEST(WritingModeUtilsTest,PhysicalToLogicalHorizontalRtl)39 TEST(WritingModeUtilsTest, PhysicalToLogicalHorizontalRtl) {
40 PhysicalToLogical<int> converter(
41 {WritingMode::kHorizontalTb, TextDirection::kRtl}, kTop, kRight, kBottom,
42 kLeft);
43 EXPECT_EQ(kRight, converter.InlineStart());
44 EXPECT_EQ(kLeft, converter.InlineEnd());
45 EXPECT_EQ(kTop, converter.BlockStart());
46 EXPECT_EQ(kBottom, converter.BlockEnd());
47 EXPECT_EQ(kLeft, converter.LineLeft());
48 EXPECT_EQ(kRight, converter.LineRight());
49 EXPECT_EQ(kTop, converter.Over());
50 EXPECT_EQ(kBottom, converter.Under());
51 CheckLegacyLogicalDirections(converter);
52 }
53
TEST(WritingModeUtilsTest,PhysicalToLogicalVlrLtr)54 TEST(WritingModeUtilsTest, PhysicalToLogicalVlrLtr) {
55 PhysicalToLogical<int> converter(
56 {WritingMode::kVerticalLr, TextDirection::kLtr}, kTop, kRight, kBottom,
57 kLeft);
58 EXPECT_EQ(kTop, converter.InlineStart());
59 EXPECT_EQ(kBottom, converter.InlineEnd());
60 EXPECT_EQ(kLeft, converter.BlockStart());
61 EXPECT_EQ(kRight, converter.BlockEnd());
62 EXPECT_EQ(kTop, converter.LineLeft());
63 EXPECT_EQ(kBottom, converter.LineRight());
64 EXPECT_EQ(kRight, converter.Over());
65 EXPECT_EQ(kLeft, converter.Under());
66 CheckLegacyLogicalDirections(converter);
67 }
68
TEST(WritingModeUtilsTest,PhysicalToLogicalVlrRtl)69 TEST(WritingModeUtilsTest, PhysicalToLogicalVlrRtl) {
70 PhysicalToLogical<int> converter(
71 {WritingMode::kVerticalLr, TextDirection::kRtl}, kTop, kRight, kBottom,
72 kLeft);
73 EXPECT_EQ(kBottom, converter.InlineStart());
74 EXPECT_EQ(kTop, converter.InlineEnd());
75 EXPECT_EQ(kLeft, converter.BlockStart());
76 EXPECT_EQ(kRight, converter.BlockEnd());
77 EXPECT_EQ(kTop, converter.LineLeft());
78 EXPECT_EQ(kBottom, converter.LineRight());
79 EXPECT_EQ(kRight, converter.Over());
80 EXPECT_EQ(kLeft, converter.Under());
81 CheckLegacyLogicalDirections(converter);
82 }
83
TEST(WritingModeUtilsTest,PhysicalToLogicalVrlLtr)84 TEST(WritingModeUtilsTest, PhysicalToLogicalVrlLtr) {
85 PhysicalToLogical<int> converter(
86 {WritingMode::kVerticalRl, TextDirection::kLtr}, kTop, kRight, kBottom,
87 kLeft);
88 EXPECT_EQ(kTop, converter.InlineStart());
89 EXPECT_EQ(kBottom, converter.InlineEnd());
90 EXPECT_EQ(kRight, converter.BlockStart());
91 EXPECT_EQ(kLeft, converter.BlockEnd());
92 EXPECT_EQ(kTop, converter.LineLeft());
93 EXPECT_EQ(kBottom, converter.LineRight());
94 EXPECT_EQ(kRight, converter.Over());
95 EXPECT_EQ(kLeft, converter.Under());
96 CheckLegacyLogicalDirections(converter);
97 }
98
TEST(WritingModeUtilsTest,PhysicalToLogicalVrlRtl)99 TEST(WritingModeUtilsTest, PhysicalToLogicalVrlRtl) {
100 PhysicalToLogical<int> converter(
101 {WritingMode::kVerticalRl, TextDirection::kRtl}, kTop, kRight, kBottom,
102 kLeft);
103 EXPECT_EQ(kBottom, converter.InlineStart());
104 EXPECT_EQ(kTop, converter.InlineEnd());
105 EXPECT_EQ(kRight, converter.BlockStart());
106 EXPECT_EQ(kLeft, converter.BlockEnd());
107 EXPECT_EQ(kTop, converter.LineLeft());
108 EXPECT_EQ(kBottom, converter.LineRight());
109 EXPECT_EQ(kRight, converter.Over());
110 EXPECT_EQ(kLeft, converter.Under());
111 CheckLegacyLogicalDirections(converter);
112 }
113
114 enum { kInlineStart = 1000, kInlineEnd, kBlockStart, kBlockEnd };
115
TEST(WritingModeUtilsTest,LogicalToPhysicalHorizontalLtr)116 TEST(WritingModeUtilsTest, LogicalToPhysicalHorizontalLtr) {
117 LogicalToPhysical<int> converter(
118 {WritingMode::kHorizontalTb, TextDirection::kLtr}, kInlineStart,
119 kInlineEnd, kBlockStart, kBlockEnd);
120 EXPECT_EQ(kInlineStart, converter.Left());
121 EXPECT_EQ(kInlineEnd, converter.Right());
122 EXPECT_EQ(kBlockStart, converter.Top());
123 EXPECT_EQ(kBlockEnd, converter.Bottom());
124 }
125
TEST(WritingModeUtilsTest,LogicalToPhysicalHorizontalRtl)126 TEST(WritingModeUtilsTest, LogicalToPhysicalHorizontalRtl) {
127 LogicalToPhysical<int> converter(
128 {WritingMode::kHorizontalTb, TextDirection::kRtl}, kInlineStart,
129 kInlineEnd, kBlockStart, kBlockEnd);
130 EXPECT_EQ(kInlineEnd, converter.Left());
131 EXPECT_EQ(kInlineStart, converter.Right());
132 EXPECT_EQ(kBlockStart, converter.Top());
133 EXPECT_EQ(kBlockEnd, converter.Bottom());
134 }
135
TEST(WritingModeUtilsTest,LogicalToPhysicalVlrLtr)136 TEST(WritingModeUtilsTest, LogicalToPhysicalVlrLtr) {
137 LogicalToPhysical<int> converter(
138 {WritingMode::kVerticalLr, TextDirection::kLtr}, kInlineStart, kInlineEnd,
139 kBlockStart, kBlockEnd);
140 EXPECT_EQ(kBlockStart, converter.Left());
141 EXPECT_EQ(kBlockEnd, converter.Right());
142 EXPECT_EQ(kInlineStart, converter.Top());
143 EXPECT_EQ(kInlineEnd, converter.Bottom());
144 }
145
TEST(WritingModeUtilsTest,LogicalToPhysicalVlrRtl)146 TEST(WritingModeUtilsTest, LogicalToPhysicalVlrRtl) {
147 LogicalToPhysical<int> converter(
148 {WritingMode::kVerticalLr, TextDirection::kRtl}, kInlineStart, kInlineEnd,
149 kBlockStart, kBlockEnd);
150 EXPECT_EQ(kBlockStart, converter.Left());
151 EXPECT_EQ(kBlockEnd, converter.Right());
152 EXPECT_EQ(kInlineEnd, converter.Top());
153 EXPECT_EQ(kInlineStart, converter.Bottom());
154 }
155
TEST(WritingModeUtilsTest,LogicalToPhysicalVrlLtr)156 TEST(WritingModeUtilsTest, LogicalToPhysicalVrlLtr) {
157 LogicalToPhysical<int> converter(
158 {WritingMode::kVerticalRl, TextDirection::kLtr}, kInlineStart, kInlineEnd,
159 kBlockStart, kBlockEnd);
160 EXPECT_EQ(kBlockEnd, converter.Left());
161 EXPECT_EQ(kBlockStart, converter.Right());
162 EXPECT_EQ(kInlineStart, converter.Top());
163 EXPECT_EQ(kInlineEnd, converter.Bottom());
164 }
165
TEST(WritingModeUtilsTest,LogicalToPhysicalVrlRtl)166 TEST(WritingModeUtilsTest, LogicalToPhysicalVrlRtl) {
167 LogicalToPhysical<int> converter(
168 {WritingMode::kVerticalRl, TextDirection::kRtl}, kInlineStart, kInlineEnd,
169 kBlockStart, kBlockEnd);
170 EXPECT_EQ(kBlockEnd, converter.Left());
171 EXPECT_EQ(kBlockStart, converter.Right());
172 EXPECT_EQ(kInlineEnd, converter.Top());
173 EXPECT_EQ(kInlineStart, converter.Bottom());
174 }
175
176 class PhysicalValues {
177 STACK_ALLOCATED();
178
179 public:
Top() const180 int Top() const { return top_; }
Right() const181 int Right() const { return right_; }
Bottom() const182 int Bottom() const { return bottom_; }
Left() const183 int Left() const { return left_; }
SetTop(int top)184 void SetTop(int top) { top_ = top; }
SetRight(int right)185 void SetRight(int right) { right_ = right; }
SetBottom(int bottom)186 void SetBottom(int bottom) { bottom_ = bottom; }
SetLeft(int left)187 void SetLeft(int left) { left_ = left; }
188
189 private:
190 int top_ = kTop;
191 int right_ = kRight;
192 int bottom_ = kBottom;
193 int left_ = kLeft;
194 };
195
TEST(WritingModeUtilsTest,PhysicalToLogicalGetter)196 TEST(WritingModeUtilsTest, PhysicalToLogicalGetter) {
197 PhysicalValues physical_values;
198 PhysicalToLogicalGetter<int, PhysicalValues> getter(
199 {WritingMode::kVerticalRl, TextDirection::kRtl}, physical_values,
200 &PhysicalValues::Top, &PhysicalValues::Right, &PhysicalValues::Bottom,
201 &PhysicalValues::Left);
202
203 EXPECT_EQ(kBottom, getter.InlineStart());
204 EXPECT_EQ(kTop, getter.InlineEnd());
205 EXPECT_EQ(kRight, getter.BlockStart());
206 EXPECT_EQ(kLeft, getter.BlockEnd());
207 EXPECT_EQ(kTop, getter.LineLeft());
208 EXPECT_EQ(kBottom, getter.LineRight());
209 EXPECT_EQ(kRight, getter.Over());
210 EXPECT_EQ(kLeft, getter.Under());
211 CheckLegacyLogicalDirections(getter);
212 }
213
TEST(WritingModeUtilsTest,LogicalToPhysicalSetter)214 TEST(WritingModeUtilsTest, LogicalToPhysicalSetter) {
215 PhysicalValues physical_values;
216 LogicalToPhysicalSetter<int, PhysicalValues> setter(
217 {WritingMode::kVerticalRl, TextDirection::kRtl}, physical_values,
218 &PhysicalValues::SetTop, &PhysicalValues::SetRight,
219 &PhysicalValues::SetBottom, &PhysicalValues::SetLeft);
220 setter.SetInlineStart(kInlineStart);
221 setter.SetInlineEnd(kInlineEnd);
222 setter.SetBlockStart(kBlockStart);
223 setter.SetBlockEnd(kBlockEnd);
224
225 EXPECT_EQ(kBlockEnd, physical_values.Left());
226 EXPECT_EQ(kBlockStart, physical_values.Right());
227 EXPECT_EQ(kInlineEnd, physical_values.Top());
228 EXPECT_EQ(kInlineStart, physical_values.Bottom());
229
230 setter.SetStart(kInlineStart);
231 setter.SetEnd(kInlineEnd);
232 setter.SetBefore(kBlockStart);
233 setter.SetAfter(kBlockEnd);
234
235 EXPECT_EQ(kBlockEnd, physical_values.Left());
236 EXPECT_EQ(kBlockStart, physical_values.Right());
237 EXPECT_EQ(kInlineEnd, physical_values.Top());
238 EXPECT_EQ(kInlineStart, physical_values.Bottom());
239
240 setter.SetLineRight(kInlineStart);
241 setter.SetLineLeft(kInlineEnd);
242 setter.SetOver(kBlockStart);
243 setter.SetUnder(kBlockEnd);
244
245 EXPECT_EQ(kBlockEnd, physical_values.Left());
246 EXPECT_EQ(kBlockStart, physical_values.Right());
247 EXPECT_EQ(kInlineEnd, physical_values.Top());
248 EXPECT_EQ(kInlineStart, physical_values.Bottom());
249 }
250
251 class LogicalValues {
252 STACK_ALLOCATED();
253
254 public:
InlineStart() const255 int InlineStart() const { return inline_start_; }
InlineEnd() const256 int InlineEnd() const { return inline_end_; }
BlockStart() const257 int BlockStart() const { return block_start_; }
BlockEnd() const258 int BlockEnd() const { return block_end_; }
SetInlineStart(int inline_start)259 void SetInlineStart(int inline_start) { inline_start_ = inline_start; }
SetInlineEnd(int inline_end)260 void SetInlineEnd(int inline_end) { inline_end_ = inline_end; }
SetBlockStart(int block_start)261 void SetBlockStart(int block_start) { block_start_ = block_start; }
SetBlockEnd(int block_end)262 void SetBlockEnd(int block_end) { block_end_ = block_end; }
263
264 private:
265 int inline_start_ = kInlineStart;
266 int inline_end_ = kInlineEnd;
267 int block_start_ = kBlockStart;
268 int block_end_ = kBlockEnd;
269 };
270
TEST(WritingModeUtilsTest,LogicalToPhysicalGetter)271 TEST(WritingModeUtilsTest, LogicalToPhysicalGetter) {
272 LogicalValues logical_values;
273 LogicalToPhysicalGetter<int, LogicalValues> getter(
274 {WritingMode::kVerticalRl, TextDirection::kRtl}, logical_values,
275 &LogicalValues::InlineStart, &LogicalValues::InlineEnd,
276 &LogicalValues::BlockStart, &LogicalValues::BlockEnd);
277
278 EXPECT_EQ(kBlockEnd, getter.Left());
279 EXPECT_EQ(kBlockStart, getter.Right());
280 EXPECT_EQ(kInlineEnd, getter.Top());
281 EXPECT_EQ(kInlineStart, getter.Bottom());
282 }
283
TEST(WritingModeUtilsTest,PhysicalToLogicalSetter)284 TEST(WritingModeUtilsTest, PhysicalToLogicalSetter) {
285 LogicalValues logical_values;
286 PhysicalToLogicalSetter<int, LogicalValues> setter(
287 {WritingMode::kVerticalRl, TextDirection::kRtl}, logical_values,
288 &LogicalValues::SetInlineStart, &LogicalValues::SetInlineEnd,
289 &LogicalValues::SetBlockStart, &LogicalValues::SetBlockEnd);
290 setter.SetTop(kTop);
291 setter.SetRight(kRight);
292 setter.SetBottom(kBottom);
293 setter.SetLeft(kLeft);
294
295 EXPECT_EQ(kBottom, logical_values.InlineStart());
296 EXPECT_EQ(kTop, logical_values.InlineEnd());
297 EXPECT_EQ(kRight, logical_values.BlockStart());
298 EXPECT_EQ(kLeft, logical_values.BlockEnd());
299 }
300
301 } // namespace
302
303 } // namespace blink
304