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