1 // Copyright 2018 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/core/editing/local_caret_rect.h"
6 
7 #include "third_party/blink/renderer/core/editing/position_with_affinity.h"
8 #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
9 #include "third_party/blink/renderer/core/editing/text_affinity.h"
10 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
11 #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
12 
13 namespace blink {
14 
15 class LocalCaretRectBidiTest : public EditingTestBase {};
16 
17 // Helper class to run the same test code with and without LayoutNG
18 class ParameterizedLocalCaretRectBidiTest
19     : public testing::WithParamInterface<bool>,
20       private ScopedLayoutNGForTest,
21       public LocalCaretRectBidiTest {
22  public:
ParameterizedLocalCaretRectBidiTest()23   ParameterizedLocalCaretRectBidiTest() : ScopedLayoutNGForTest(GetParam()) {}
24 
25  protected:
LayoutNGEnabled() const26   bool LayoutNGEnabled() const {
27     return RuntimeEnabledFeatures::LayoutNGEnabled();
28   }
29 };
30 
31 INSTANTIATE_TEST_SUITE_P(All,
32                          ParameterizedLocalCaretRectBidiTest,
33                          testing::Bool());
34 
35 // This file contains script-generated tests for LocalCaretRectOfPosition()
36 // that are related to Bidirectional text. The test cases are only for
37 // behavior recording purposes, and do not necessarily reflect the
38 // correct/desired behavior.
39 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterRtlRunTouchingLineBoundary)40 TEST_P(ParameterizedLocalCaretRectBidiTest,
41        InLtrBlockLtrBaseRunAfterRtlRunTouchingLineBoundary) {
42   // Sample: A B C|d e f
43   // Bidi:   1 1 1 0 0 0
44   // Visual: C B A|d e f
45   LoadAhem();
46   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
47   const Position position = SetCaretTextToBody(
48       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>ABC</bdo>|def</bdo></div>");
49   const PositionWithAffinity position_with_affinity(position,
50                                                     TextAffinity::kDownstream);
51   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
52             LocalCaretRectOfPosition(position_with_affinity).rect);
53 }
54 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterRtlRun)55 TEST_P(ParameterizedLocalCaretRectBidiTest, InLtrBlockLtrBaseRunAfterRtlRun) {
56   // Sample: g h i A B C|d e f
57   // Bidi:   0 0 0 1 1 1 0 0 0
58   // Visual: g h i C B A|d e f
59   LoadAhem();
60   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
61   const Position position = SetCaretTextToBody(
62       "<div dir=ltr><bdo dir=ltr>ghi<bdo dir=rtl>ABC</bdo>|def</bdo></div>");
63   const PositionWithAffinity position_with_affinity(position,
64                                                     TextAffinity::kDownstream);
65   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
66             LocalCaretRectOfPosition(position_with_affinity).rect);
67 }
68 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterRtlRunTouchingLineBoundaryAtDeepPosition)69 TEST_P(ParameterizedLocalCaretRectBidiTest,
70        InLtrBlockLtrBaseRunAfterRtlRunTouchingLineBoundaryAtDeepPosition) {
71   // Sample: A B C|d e f
72   // Bidi:   1 1 1 0 0 0
73   // Visual: C B A|d e f
74   LoadAhem();
75   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
76   const Position position = SetCaretTextToBody(
77       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>ABC|</bdo>def</bdo></div>");
78   const PositionWithAffinity position_with_affinity(position,
79                                                     TextAffinity::kDownstream);
80   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
81             LocalCaretRectOfPosition(position_with_affinity).rect);
82 }
83 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterRtlRunAtDeepPosition)84 TEST_P(ParameterizedLocalCaretRectBidiTest,
85        InLtrBlockLtrBaseRunAfterRtlRunAtDeepPosition) {
86   // Sample: g h i A B C|d e f
87   // Bidi:   0 0 0 1 1 1 0 0 0
88   // Visual: g h i C B A|d e f
89   LoadAhem();
90   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
91   const Position position = SetCaretTextToBody(
92       "<div dir=ltr><bdo dir=ltr>ghi<bdo dir=rtl>ABC|</bdo>def</bdo></div>");
93   const PositionWithAffinity position_with_affinity(position,
94                                                     TextAffinity::kDownstream);
95   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
96             LocalCaretRectOfPosition(position_with_affinity).rect);
97 }
98 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterTwoNestedRuns)99 TEST_P(ParameterizedLocalCaretRectBidiTest,
100        InLtrBlockLtrBaseRunAfterTwoNestedRuns) {
101   // Sample: D E F a b c|g h i
102   // Bidi:   1 1 1 2 2 2 0 0 0
103   // Visual: a b c F E D|g h i
104   LoadAhem();
105   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
106   const Position position = SetCaretTextToBody(
107       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>DEF<bdo "
108       "dir=ltr>abc</bdo></bdo>|ghi</bdo></div>");
109   const PositionWithAffinity position_with_affinity(position,
110                                                     TextAffinity::kDownstream);
111   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
112             LocalCaretRectOfPosition(position_with_affinity).rect);
113 }
114 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterTwoNestedRunsAtDeepPosition)115 TEST_P(ParameterizedLocalCaretRectBidiTest,
116        InLtrBlockLtrBaseRunAfterTwoNestedRunsAtDeepPosition) {
117   // Sample: D E F a b c|g h i
118   // Bidi:   1 1 1 2 2 2 0 0 0
119   // Visual: a b c F E D|g h i
120   LoadAhem();
121   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
122   const Position position = SetCaretTextToBody(
123       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>DEF<bdo "
124       "dir=ltr>abc|</bdo></bdo>ghi</bdo></div>");
125   const PositionWithAffinity position_with_affinity(position,
126                                                     TextAffinity::kDownstream);
127   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
128             LocalCaretRectOfPosition(position_with_affinity).rect);
129 }
130 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterThreeNestedRuns)131 TEST_P(ParameterizedLocalCaretRectBidiTest,
132        InLtrBlockLtrBaseRunAfterThreeNestedRuns) {
133   // Sample: G H I d e f A B C|j k l
134   // Bidi:   1 1 1 2 2 2 3 3 3 0 0 0
135   // Visual: d e f C B A I H G|j k l
136   LoadAhem();
137   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
138   const Position position = SetCaretTextToBody(
139       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>GHI<bdo dir=ltr>def<bdo "
140       "dir=rtl>ABC</bdo></bdo></bdo>|jkl</bdo></div>");
141   const PositionWithAffinity position_with_affinity(position,
142                                                     TextAffinity::kDownstream);
143   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
144   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(60, 0, 1, 10)
145                               : PhysicalRect(90, 0, 1, 10),
146             LocalCaretRectOfPosition(position_with_affinity).rect);
147 }
148 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterThreeNestedRunsAtDeepPosition)149 TEST_P(ParameterizedLocalCaretRectBidiTest,
150        InLtrBlockLtrBaseRunAfterThreeNestedRunsAtDeepPosition) {
151   // Sample: G H I d e f A B C|j k l
152   // Bidi:   1 1 1 2 2 2 3 3 3 0 0 0
153   // Visual: d e f C B A I H G|j k l
154   LoadAhem();
155   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
156   const Position position = SetCaretTextToBody(
157       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>GHI<bdo dir=ltr>def<bdo "
158       "dir=rtl>ABC|</bdo></bdo></bdo>jkl</bdo></div>");
159   const PositionWithAffinity position_with_affinity(position,
160                                                     TextAffinity::kDownstream);
161   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
162   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(60, 0, 1, 10)
163                               : PhysicalRect(90, 0, 1, 10),
164             LocalCaretRectOfPosition(position_with_affinity).rect);
165 }
166 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterFourNestedRuns)167 TEST_P(ParameterizedLocalCaretRectBidiTest,
168        InLtrBlockLtrBaseRunAfterFourNestedRuns) {
169   // Sample: J K L g h i D E F a b c|m n o
170   // Bidi:   1 1 1 2 2 2 3 3 3 4 4 4 0 0 0
171   // Visual: g h i a b c F E D L K J|m n o
172   LoadAhem();
173   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
174   const Position position = SetCaretTextToBody(
175       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>JKL<bdo dir=ltr>ghi<bdo "
176       "dir=rtl>DEF<bdo dir=ltr>abc</bdo></bdo></bdo></bdo>|mno</bdo></div>");
177   const PositionWithAffinity position_with_affinity(position,
178                                                     TextAffinity::kDownstream);
179   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
180   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(90, 0, 1, 10)
181                               : PhysicalRect(120, 0, 1, 10),
182             LocalCaretRectOfPosition(position_with_affinity).rect);
183 }
184 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunAfterFourNestedRunsAtDeepPosition)185 TEST_P(ParameterizedLocalCaretRectBidiTest,
186        InLtrBlockLtrBaseRunAfterFourNestedRunsAtDeepPosition) {
187   // Sample: J K L g h i D E F a b c|m n o
188   // Bidi:   1 1 1 2 2 2 3 3 3 4 4 4 0 0 0
189   // Visual: g h i a b c F E D L K J|m n o
190   LoadAhem();
191   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
192   const Position position = SetCaretTextToBody(
193       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>JKL<bdo dir=ltr>ghi<bdo "
194       "dir=rtl>DEF<bdo dir=ltr>abc|</bdo></bdo></bdo></bdo>mno</bdo></div>");
195   const PositionWithAffinity position_with_affinity(position,
196                                                     TextAffinity::kDownstream);
197   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
198   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(90, 0, 1, 10)
199                               : PhysicalRect(120, 0, 1, 10),
200             LocalCaretRectOfPosition(position_with_affinity).rect);
201 }
202 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeRtlRunTouchingLineBoundary)203 TEST_P(ParameterizedLocalCaretRectBidiTest,
204        InLtrBlockLtrBaseRunBeforeRtlRunTouchingLineBoundary) {
205   // Sample: d e f|A B C
206   // Bidi:   0 0 0 1 1 1
207   // Visual: d e f|C B A
208   LoadAhem();
209   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
210   const Position position = SetCaretTextToBody(
211       "<div dir=ltr><bdo dir=ltr>def|<bdo dir=rtl>ABC</bdo></bdo></div>");
212   const PositionWithAffinity position_with_affinity(position,
213                                                     TextAffinity::kDownstream);
214   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
215             LocalCaretRectOfPosition(position_with_affinity).rect);
216 }
217 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeRtlRun)218 TEST_P(ParameterizedLocalCaretRectBidiTest, InLtrBlockLtrBaseRunBeforeRtlRun) {
219   // Sample: d e f|A B C g h i
220   // Bidi:   0 0 0 1 1 1 0 0 0
221   // Visual: d e f|C B A g h i
222   LoadAhem();
223   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
224   const Position position = SetCaretTextToBody(
225       "<div dir=ltr><bdo dir=ltr>def|<bdo dir=rtl>ABC</bdo>ghi</bdo></div>");
226   const PositionWithAffinity position_with_affinity(position,
227                                                     TextAffinity::kDownstream);
228   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
229             LocalCaretRectOfPosition(position_with_affinity).rect);
230 }
231 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeRtlRunTouchingLineBoundaryAtDeepPosition)232 TEST_P(ParameterizedLocalCaretRectBidiTest,
233        InLtrBlockLtrBaseRunBeforeRtlRunTouchingLineBoundaryAtDeepPosition) {
234   // Sample: d e f|A B C
235   // Bidi:   0 0 0 1 1 1
236   // Visual: d e f|C B A
237   LoadAhem();
238   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
239   const Position position = SetCaretTextToBody(
240       "<div dir=ltr><bdo dir=ltr>def<bdo dir=rtl>|ABC</bdo></bdo></div>");
241   const PositionWithAffinity position_with_affinity(position,
242                                                     TextAffinity::kDownstream);
243   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
244             LocalCaretRectOfPosition(position_with_affinity).rect);
245 }
246 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeRtlRunAtDeepPosition)247 TEST_P(ParameterizedLocalCaretRectBidiTest,
248        InLtrBlockLtrBaseRunBeforeRtlRunAtDeepPosition) {
249   // Sample: d e f|A B C g h i
250   // Bidi:   0 0 0 1 1 1 0 0 0
251   // Visual: d e f|C B A g h i
252   LoadAhem();
253   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
254   const Position position = SetCaretTextToBody(
255       "<div dir=ltr><bdo dir=ltr>def<bdo dir=rtl>|ABC</bdo>ghi</bdo></div>");
256   const PositionWithAffinity position_with_affinity(position,
257                                                     TextAffinity::kDownstream);
258   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
259             LocalCaretRectOfPosition(position_with_affinity).rect);
260 }
261 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeTwoNestedRuns)262 TEST_P(ParameterizedLocalCaretRectBidiTest,
263        InLtrBlockLtrBaseRunBeforeTwoNestedRuns) {
264   // Sample: g h i|a b c D E F
265   // Bidi:   0 0 0 2 2 2 1 1 1
266   // Visual: g h i|F E D a b c
267   LoadAhem();
268   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
269   const Position position = SetCaretTextToBody(
270       "<div dir=ltr><bdo dir=ltr>ghi|<bdo dir=rtl><bdo "
271       "dir=ltr>abc</bdo>DEF</bdo></bdo></div>");
272   const PositionWithAffinity position_with_affinity(position,
273                                                     TextAffinity::kDownstream);
274   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
275             LocalCaretRectOfPosition(position_with_affinity).rect);
276 }
277 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeTwoNestedRunsAtDeepPosition)278 TEST_P(ParameterizedLocalCaretRectBidiTest,
279        InLtrBlockLtrBaseRunBeforeTwoNestedRunsAtDeepPosition) {
280   // Sample: g h i|a b c D E F
281   // Bidi:   0 0 0 2 2 2 1 1 1
282   // Visual: g h i|F E D a b c
283   LoadAhem();
284   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
285   const Position position = SetCaretTextToBody(
286       "<div dir=ltr><bdo dir=ltr>ghi<bdo dir=rtl><bdo "
287       "dir=ltr>|abc</bdo>DEF</bdo></bdo></div>");
288   const PositionWithAffinity position_with_affinity(position,
289                                                     TextAffinity::kDownstream);
290   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
291             LocalCaretRectOfPosition(position_with_affinity).rect);
292 }
293 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeThreeNestedRuns)294 TEST_P(ParameterizedLocalCaretRectBidiTest,
295        InLtrBlockLtrBaseRunBeforeThreeNestedRuns) {
296   // Sample: j k l|A B C d e f G H I
297   // Bidi:   0 0 0 3 3 3 2 2 2 1 1 1
298   // Visual: j k l I H G|C B A d e f
299   LoadAhem();
300   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
301   const Position position = SetCaretTextToBody(
302       "<div dir=ltr><bdo dir=ltr>jkl|<bdo dir=rtl><bdo dir=ltr><bdo "
303       "dir=rtl>ABC</bdo>def</bdo>GHI</bdo></bdo></div>");
304   const PositionWithAffinity position_with_affinity(position,
305                                                     TextAffinity::kDownstream);
306   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
307   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(30, 0, 1, 10)
308                               : PhysicalRect(60, 0, 1, 10),
309             LocalCaretRectOfPosition(position_with_affinity).rect);
310 }
311 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeThreeNestedRunsAtDeepPosition)312 TEST_P(ParameterizedLocalCaretRectBidiTest,
313        InLtrBlockLtrBaseRunBeforeThreeNestedRunsAtDeepPosition) {
314   // Sample: j k l|A B C d e f G H I
315   // Bidi:   0 0 0 3 3 3 2 2 2 1 1 1
316   // Visual: j k l I H G|C B A d e f
317   LoadAhem();
318   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
319   const Position position = SetCaretTextToBody(
320       "<div dir=ltr><bdo dir=ltr>jkl<bdo dir=rtl><bdo dir=ltr><bdo "
321       "dir=rtl>|ABC</bdo>def</bdo>GHI</bdo></bdo></div>");
322   const PositionWithAffinity position_with_affinity(position,
323                                                     TextAffinity::kDownstream);
324   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
325   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(30, 0, 1, 10)
326                               : PhysicalRect(60, 0, 1, 10),
327             LocalCaretRectOfPosition(position_with_affinity).rect);
328 }
329 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeFourNestedRuns)330 TEST_P(ParameterizedLocalCaretRectBidiTest,
331        InLtrBlockLtrBaseRunBeforeFourNestedRuns) {
332   // Sample: m n o|a b c D E F g h i J K L
333   // Bidi:   0 0 0 4 4 4 3 3 3 2 2 2 1 1 1
334   // Visual: m n o L K J|F E D a b c g h i
335   LoadAhem();
336   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
337   const Position position = SetCaretTextToBody(
338       "<div dir=ltr><bdo dir=ltr>mno|<bdo dir=rtl><bdo dir=ltr><bdo "
339       "dir=rtl><bdo dir=ltr>abc</bdo>DEF</bdo>ghi</bdo>JKL</bdo></bdo></div>");
340   const PositionWithAffinity position_with_affinity(position,
341                                                     TextAffinity::kDownstream);
342   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
343   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(30, 0, 1, 10)
344                               : PhysicalRect(60, 0, 1, 10),
345             LocalCaretRectOfPosition(position_with_affinity).rect);
346 }
347 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLtrBaseRunBeforeFourNestedRunsAtDeepPosition)348 TEST_P(ParameterizedLocalCaretRectBidiTest,
349        InLtrBlockLtrBaseRunBeforeFourNestedRunsAtDeepPosition) {
350   // Sample: m n o|a b c D E F g h i J K L
351   // Bidi:   0 0 0 4 4 4 3 3 3 2 2 2 1 1 1
352   // Visual: m n o L K J|F E D a b c g h i
353   LoadAhem();
354   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
355   const Position position = SetCaretTextToBody(
356       "<div dir=ltr><bdo dir=ltr>mno<bdo dir=rtl><bdo dir=ltr><bdo "
357       "dir=rtl><bdo dir=ltr>|abc</bdo>DEF</bdo>ghi</bdo>JKL</bdo></bdo></div>");
358   const PositionWithAffinity position_with_affinity(position,
359                                                     TextAffinity::kDownstream);
360   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
361   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(30, 0, 1, 10)
362                               : PhysicalRect(60, 0, 1, 10),
363             LocalCaretRectOfPosition(position_with_affinity).rect);
364 }
365 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterLtrRunTouchingLineBoundary)366 TEST_P(ParameterizedLocalCaretRectBidiTest,
367        InLtrBlockRtlBaseRunAfterLtrRunTouchingLineBoundary) {
368   // Sample: a b c|D E F
369   // Bidi:   2 2 2 1 1 1
370   // Visual: F E D a b c|
371   LoadAhem();
372   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
373   const Position position = SetCaretTextToBody(
374       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>abc</bdo>|DEF</bdo></div>");
375   const PositionWithAffinity position_with_affinity(position,
376                                                     TextAffinity::kDownstream);
377   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
378             LocalCaretRectOfPosition(position_with_affinity).rect);
379 }
380 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterLtrRun)381 TEST_P(ParameterizedLocalCaretRectBidiTest, InLtrBlockRtlBaseRunAfterLtrRun) {
382   // Sample: G H I a b c|D E F
383   // Bidi:   1 1 1 2 2 2 1 1 1
384   // Visual: F E D a b c|I H G
385   LoadAhem();
386   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
387   const Position position = SetCaretTextToBody(
388       "<div dir=ltr><bdo dir=rtl>GHI<bdo dir=ltr>abc</bdo>|DEF</bdo></div>");
389   const PositionWithAffinity position_with_affinity(position,
390                                                     TextAffinity::kDownstream);
391   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
392             LocalCaretRectOfPosition(position_with_affinity).rect);
393 }
394 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterLtrRunTouchingLineBoundaryAtDeepPosition)395 TEST_P(ParameterizedLocalCaretRectBidiTest,
396        InLtrBlockRtlBaseRunAfterLtrRunTouchingLineBoundaryAtDeepPosition) {
397   // Sample: a b c|D E F
398   // Bidi:   2 2 2 1 1 1
399   // Visual: F E D a b c|
400   LoadAhem();
401   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
402   const Position position = SetCaretTextToBody(
403       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>abc|</bdo>DEF</bdo></div>");
404   const PositionWithAffinity position_with_affinity(position,
405                                                     TextAffinity::kDownstream);
406   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
407             LocalCaretRectOfPosition(position_with_affinity).rect);
408 }
409 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterLtrRunAtDeepPosition)410 TEST_P(ParameterizedLocalCaretRectBidiTest,
411        InLtrBlockRtlBaseRunAfterLtrRunAtDeepPosition) {
412   // Sample: G H I a b c|D E F
413   // Bidi:   1 1 1 2 2 2 1 1 1
414   // Visual: F E D a b c|I H G
415   LoadAhem();
416   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
417   const Position position = SetCaretTextToBody(
418       "<div dir=ltr><bdo dir=rtl>GHI<bdo dir=ltr>abc|</bdo>DEF</bdo></div>");
419   const PositionWithAffinity position_with_affinity(position,
420                                                     TextAffinity::kDownstream);
421   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
422             LocalCaretRectOfPosition(position_with_affinity).rect);
423 }
424 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterTwoNestedRuns)425 TEST_P(ParameterizedLocalCaretRectBidiTest,
426        InLtrBlockRtlBaseRunAfterTwoNestedRuns) {
427   // Sample: d e f A B C|G H I
428   // Bidi:   2 2 2 3 3 3 1 1 1
429   // Visual: I H G d e f C B A|
430   LoadAhem();
431   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
432   const Position position = SetCaretTextToBody(
433       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>def<bdo "
434       "dir=rtl>ABC</bdo></bdo>|GHI</bdo></div>");
435   const PositionWithAffinity position_with_affinity(position,
436                                                     TextAffinity::kDownstream);
437   EXPECT_EQ(PhysicalRect(90, 0, 1, 10),
438             LocalCaretRectOfPosition(position_with_affinity).rect);
439 }
440 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterTwoNestedRunsAtDeepPosition)441 TEST_P(ParameterizedLocalCaretRectBidiTest,
442        InLtrBlockRtlBaseRunAfterTwoNestedRunsAtDeepPosition) {
443   // Sample: d e f A B C|G H I
444   // Bidi:   2 2 2 3 3 3 1 1 1
445   // Visual: I H G d e f C B A|
446   LoadAhem();
447   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
448   const Position position = SetCaretTextToBody(
449       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>def<bdo "
450       "dir=rtl>ABC|</bdo></bdo>GHI</bdo></div>");
451   const PositionWithAffinity position_with_affinity(position,
452                                                     TextAffinity::kDownstream);
453   EXPECT_EQ(PhysicalRect(90, 0, 1, 10),
454             LocalCaretRectOfPosition(position_with_affinity).rect);
455 }
456 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterThreeNestedRuns)457 TEST_P(ParameterizedLocalCaretRectBidiTest,
458        InLtrBlockRtlBaseRunAfterThreeNestedRuns) {
459   // Sample: g h i D E F a b c|J K L
460   // Bidi:   2 2 2 3 3 3 4 4 4 1 1 1
461   // Visual: L K J g h i a b c F E D|
462   LoadAhem();
463   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
464   const Position position = SetCaretTextToBody(
465       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>ghi<bdo dir=rtl>DEF<bdo "
466       "dir=ltr>abc</bdo></bdo></bdo>|JKL</bdo></div>");
467   const PositionWithAffinity position_with_affinity(position,
468                                                     TextAffinity::kDownstream);
469   EXPECT_EQ(PhysicalRect(120, 0, 1, 10),
470             LocalCaretRectOfPosition(position_with_affinity).rect);
471 }
472 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterThreeNestedRunsAtDeepPosition)473 TEST_P(ParameterizedLocalCaretRectBidiTest,
474        InLtrBlockRtlBaseRunAfterThreeNestedRunsAtDeepPosition) {
475   // Sample: g h i D E F a b c|J K L
476   // Bidi:   2 2 2 3 3 3 4 4 4 1 1 1
477   // Visual: L K J g h i a b c F E D|
478   LoadAhem();
479   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
480   const Position position = SetCaretTextToBody(
481       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>ghi<bdo dir=rtl>DEF<bdo "
482       "dir=ltr>abc|</bdo></bdo></bdo>JKL</bdo></div>");
483   const PositionWithAffinity position_with_affinity(position,
484                                                     TextAffinity::kDownstream);
485   EXPECT_EQ(PhysicalRect(120, 0, 1, 10),
486             LocalCaretRectOfPosition(position_with_affinity).rect);
487 }
488 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterFourNestedRuns)489 TEST_P(ParameterizedLocalCaretRectBidiTest,
490        InLtrBlockRtlBaseRunAfterFourNestedRuns) {
491   // Sample: j k l G H I d e f A B C|M N O
492   // Bidi:   2 2 2 3 3 3 4 4 4 5 5 5 1 1 1
493   // Visual: O N M j k l d e f C B A I H G|
494   LoadAhem();
495   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
496   const Position position = SetCaretTextToBody(
497       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>jkl<bdo dir=rtl>GHI<bdo "
498       "dir=ltr>def<bdo dir=rtl>ABC</bdo></bdo></bdo></bdo>|MNO</bdo></div>");
499   const PositionWithAffinity position_with_affinity(position,
500                                                     TextAffinity::kDownstream);
501   EXPECT_EQ(PhysicalRect(150, 0, 1, 10),
502             LocalCaretRectOfPosition(position_with_affinity).rect);
503 }
504 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunAfterFourNestedRunsAtDeepPosition)505 TEST_P(ParameterizedLocalCaretRectBidiTest,
506        InLtrBlockRtlBaseRunAfterFourNestedRunsAtDeepPosition) {
507   // Sample: j k l G H I d e f A B C|M N O
508   // Bidi:   2 2 2 3 3 3 4 4 4 5 5 5 1 1 1
509   // Visual: O N M j k l d e f C B A I H G|
510   LoadAhem();
511   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
512   const Position position = SetCaretTextToBody(
513       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>jkl<bdo dir=rtl>GHI<bdo "
514       "dir=ltr>def<bdo dir=rtl>ABC|</bdo></bdo></bdo></bdo>MNO</bdo></div>");
515   const PositionWithAffinity position_with_affinity(position,
516                                                     TextAffinity::kDownstream);
517   EXPECT_EQ(PhysicalRect(150, 0, 1, 10),
518             LocalCaretRectOfPosition(position_with_affinity).rect);
519 }
520 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeLtrRunTouchingLineBoundary)521 TEST_P(ParameterizedLocalCaretRectBidiTest,
522        InLtrBlockRtlBaseRunBeforeLtrRunTouchingLineBoundary) {
523   // Sample: D E F|a b c
524   // Bidi:   1 1 1 2 2 2
525   // Visual:|a b c F E D
526   LoadAhem();
527   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
528   const Position position = SetCaretTextToBody(
529       "<div dir=ltr><bdo dir=rtl>DEF|<bdo dir=ltr>abc</bdo></bdo></div>");
530   const PositionWithAffinity position_with_affinity(position,
531                                                     TextAffinity::kDownstream);
532   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
533             LocalCaretRectOfPosition(position_with_affinity).rect);
534 }
535 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeLtrRun)536 TEST_P(ParameterizedLocalCaretRectBidiTest, InLtrBlockRtlBaseRunBeforeLtrRun) {
537   // Sample: D E F|a b c G H I
538   // Bidi:   1 1 1 2 2 2 1 1 1
539   // Visual: I H G|a b c F E D
540   LoadAhem();
541   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
542   const Position position = SetCaretTextToBody(
543       "<div dir=ltr><bdo dir=rtl>DEF|<bdo dir=ltr>abc</bdo>GHI</bdo></div>");
544   const PositionWithAffinity position_with_affinity(position,
545                                                     TextAffinity::kDownstream);
546   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
547             LocalCaretRectOfPosition(position_with_affinity).rect);
548 }
549 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeLtrRunTouchingLineBoundaryAtDeepPosition)550 TEST_P(ParameterizedLocalCaretRectBidiTest,
551        InLtrBlockRtlBaseRunBeforeLtrRunTouchingLineBoundaryAtDeepPosition) {
552   // Sample: D E F|a b c
553   // Bidi:   1 1 1 2 2 2
554   // Visual:|a b c F E D
555   LoadAhem();
556   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
557   const Position position = SetCaretTextToBody(
558       "<div dir=ltr><bdo dir=rtl>DEF<bdo dir=ltr>|abc</bdo></bdo></div>");
559   const PositionWithAffinity position_with_affinity(position,
560                                                     TextAffinity::kDownstream);
561   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
562             LocalCaretRectOfPosition(position_with_affinity).rect);
563 }
564 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeLtrRunAtDeepPosition)565 TEST_P(ParameterizedLocalCaretRectBidiTest,
566        InLtrBlockRtlBaseRunBeforeLtrRunAtDeepPosition) {
567   // Sample: D E F|a b c G H I
568   // Bidi:   1 1 1 2 2 2 1 1 1
569   // Visual: I H G|a b c F E D
570   LoadAhem();
571   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
572   const Position position = SetCaretTextToBody(
573       "<div dir=ltr><bdo dir=rtl>DEF<bdo dir=ltr>|abc</bdo>GHI</bdo></div>");
574   const PositionWithAffinity position_with_affinity(position,
575                                                     TextAffinity::kDownstream);
576   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
577             LocalCaretRectOfPosition(position_with_affinity).rect);
578 }
579 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeTwoNestedRuns)580 TEST_P(ParameterizedLocalCaretRectBidiTest,
581        InLtrBlockRtlBaseRunBeforeTwoNestedRuns) {
582   // Sample: G H I|A B C d e f
583   // Bidi:   1 1 1 3 3 3 2 2 2
584   // Visual:|C B A d e f I H G
585   LoadAhem();
586   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
587   const Position position = SetCaretTextToBody(
588       "<div dir=ltr><bdo dir=rtl>GHI|<bdo dir=ltr><bdo "
589       "dir=rtl>ABC</bdo>def</bdo></bdo></div>");
590   const PositionWithAffinity position_with_affinity(position,
591                                                     TextAffinity::kDownstream);
592   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
593             LocalCaretRectOfPosition(position_with_affinity).rect);
594 }
595 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeTwoNestedRunsAtDeepPosition)596 TEST_P(ParameterizedLocalCaretRectBidiTest,
597        InLtrBlockRtlBaseRunBeforeTwoNestedRunsAtDeepPosition) {
598   // Sample: G H I|A B C d e f
599   // Bidi:   1 1 1 3 3 3 2 2 2
600   // Visual:|C B A d e f I H G
601   LoadAhem();
602   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
603   const Position position = SetCaretTextToBody(
604       "<div dir=ltr><bdo dir=rtl>GHI<bdo dir=ltr><bdo "
605       "dir=rtl>|ABC</bdo>def</bdo></bdo></div>");
606   const PositionWithAffinity position_with_affinity(position,
607                                                     TextAffinity::kDownstream);
608   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
609             LocalCaretRectOfPosition(position_with_affinity).rect);
610 }
611 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeThreeNestedRuns)612 TEST_P(ParameterizedLocalCaretRectBidiTest,
613        InLtrBlockRtlBaseRunBeforeThreeNestedRuns) {
614   // Sample: J K L|a b c D E F g h i
615   // Bidi:   1 1 1 4 4 4 3 3 3 2 2 2
616   // Visual:|F E D a b c g h i L K J
617   LoadAhem();
618   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
619   const Position position = SetCaretTextToBody(
620       "<div dir=ltr><bdo dir=rtl>JKL|<bdo dir=ltr><bdo dir=rtl><bdo "
621       "dir=ltr>abc</bdo>DEF</bdo>ghi</bdo></bdo></div>");
622   const PositionWithAffinity position_with_affinity(position,
623                                                     TextAffinity::kDownstream);
624   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
625             LocalCaretRectOfPosition(position_with_affinity).rect);
626 }
627 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeThreeNestedRunsAtDeepPosition)628 TEST_P(ParameterizedLocalCaretRectBidiTest,
629        InLtrBlockRtlBaseRunBeforeThreeNestedRunsAtDeepPosition) {
630   // Sample: J K L|a b c D E F g h i
631   // Bidi:   1 1 1 4 4 4 3 3 3 2 2 2
632   // Visual:|F E D a b c g h i L K J
633   LoadAhem();
634   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
635   const Position position = SetCaretTextToBody(
636       "<div dir=ltr><bdo dir=rtl>JKL<bdo dir=ltr><bdo dir=rtl><bdo "
637       "dir=ltr>|abc</bdo>DEF</bdo>ghi</bdo></bdo></div>");
638   const PositionWithAffinity position_with_affinity(position,
639                                                     TextAffinity::kDownstream);
640   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
641             LocalCaretRectOfPosition(position_with_affinity).rect);
642 }
643 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeFourNestedRuns)644 TEST_P(ParameterizedLocalCaretRectBidiTest,
645        InLtrBlockRtlBaseRunBeforeFourNestedRuns) {
646   // Sample: M N O|A B C d e f G H I j k l
647   // Bidi:   1 1 1 5 5 5 4 4 4 3 3 3 2 2 2
648   // Visual: I H G|C B A d e f j k l O N M
649   LoadAhem();
650   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
651   const Position position = SetCaretTextToBody(
652       "<div dir=ltr><bdo dir=rtl>MNO|<bdo dir=ltr><bdo dir=rtl><bdo "
653       "dir=ltr><bdo dir=rtl>ABC</bdo>def</bdo>GHI</bdo>jkl</bdo></bdo></div>");
654   const PositionWithAffinity position_with_affinity(position,
655                                                     TextAffinity::kDownstream);
656   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
657             LocalCaretRectOfPosition(position_with_affinity).rect);
658 }
659 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockRtlBaseRunBeforeFourNestedRunsAtDeepPosition)660 TEST_P(ParameterizedLocalCaretRectBidiTest,
661        InLtrBlockRtlBaseRunBeforeFourNestedRunsAtDeepPosition) {
662   // Sample: M N O|A B C d e f G H I j k l
663   // Bidi:   1 1 1 5 5 5 4 4 4 3 3 3 2 2 2
664   // Visual: I H G|C B A d e f j k l O N M
665   LoadAhem();
666   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
667   const Position position = SetCaretTextToBody(
668       "<div dir=ltr><bdo dir=rtl>MNO<bdo dir=ltr><bdo dir=rtl><bdo "
669       "dir=ltr><bdo dir=rtl>|ABC</bdo>def</bdo>GHI</bdo>jkl</bdo></bdo></div>");
670   const PositionWithAffinity position_with_affinity(position,
671                                                     TextAffinity::kDownstream);
672   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
673             LocalCaretRectOfPosition(position_with_affinity).rect);
674 }
675 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterRtlRunTouchingLineBoundary)676 TEST_P(ParameterizedLocalCaretRectBidiTest,
677        InRtlBlockLtrBaseRunAfterRtlRunTouchingLineBoundary) {
678   // Sample: A B C|d e f
679   // Bidi:   3 3 3 2 2 2
680   // Visual:|C B A d e f
681   LoadAhem();
682   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
683   const Position position = SetCaretTextToBody(
684       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>ABC</bdo>|def</bdo></div>");
685   const PositionWithAffinity position_with_affinity(position,
686                                                     TextAffinity::kDownstream);
687   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
688             LocalCaretRectOfPosition(position_with_affinity).rect);
689 }
690 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterRtlRun)691 TEST_P(ParameterizedLocalCaretRectBidiTest, InRtlBlockLtrBaseRunAfterRtlRun) {
692   // Sample: g h i A B C|d e f
693   // Bidi:   2 2 2 3 3 3 2 2 2
694   // Visual: g h i|C B A d e f
695   LoadAhem();
696   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
697   const Position position = SetCaretTextToBody(
698       "<div dir=rtl><bdo dir=ltr>ghi<bdo dir=rtl>ABC</bdo>|def</bdo></div>");
699   const PositionWithAffinity position_with_affinity(position,
700                                                     TextAffinity::kDownstream);
701   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
702             LocalCaretRectOfPosition(position_with_affinity).rect);
703 }
704 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterRtlRunTouchingLineBoundaryAtDeepPosition)705 TEST_P(ParameterizedLocalCaretRectBidiTest,
706        InRtlBlockLtrBaseRunAfterRtlRunTouchingLineBoundaryAtDeepPosition) {
707   // Sample: A B C|d e f
708   // Bidi:   3 3 3 2 2 2
709   // Visual:|C B A d e f
710   LoadAhem();
711   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
712   const Position position = SetCaretTextToBody(
713       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>ABC|</bdo>def</bdo></div>");
714   const PositionWithAffinity position_with_affinity(position,
715                                                     TextAffinity::kDownstream);
716   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
717             LocalCaretRectOfPosition(position_with_affinity).rect);
718 }
719 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterRtlRunAtDeepPosition)720 TEST_P(ParameterizedLocalCaretRectBidiTest,
721        InRtlBlockLtrBaseRunAfterRtlRunAtDeepPosition) {
722   // Sample: g h i A B C|d e f
723   // Bidi:   2 2 2 3 3 3 2 2 2
724   // Visual: g h i|C B A d e f
725   LoadAhem();
726   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
727   const Position position = SetCaretTextToBody(
728       "<div dir=rtl><bdo dir=ltr>ghi<bdo dir=rtl>ABC|</bdo>def</bdo></div>");
729   const PositionWithAffinity position_with_affinity(position,
730                                                     TextAffinity::kDownstream);
731   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
732             LocalCaretRectOfPosition(position_with_affinity).rect);
733 }
734 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterTwoNestedRuns)735 TEST_P(ParameterizedLocalCaretRectBidiTest,
736        InRtlBlockLtrBaseRunAfterTwoNestedRuns) {
737   // Sample: D E F a b c|g h i
738   // Bidi:   3 3 3 4 4 4 2 2 2
739   // Visual:|a b c F E D g h i
740   LoadAhem();
741   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
742   const Position position = SetCaretTextToBody(
743       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>DEF<bdo "
744       "dir=ltr>abc</bdo></bdo>|ghi</bdo></div>");
745   const PositionWithAffinity position_with_affinity(position,
746                                                     TextAffinity::kDownstream);
747   EXPECT_EQ(PhysicalRect(210, 0, 1, 10),
748             LocalCaretRectOfPosition(position_with_affinity).rect);
749 }
750 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterTwoNestedRunsAtDeepPosition)751 TEST_P(ParameterizedLocalCaretRectBidiTest,
752        InRtlBlockLtrBaseRunAfterTwoNestedRunsAtDeepPosition) {
753   // Sample: D E F a b c|g h i
754   // Bidi:   3 3 3 4 4 4 2 2 2
755   // Visual:|a b c F E D g h i
756   LoadAhem();
757   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
758   const Position position = SetCaretTextToBody(
759       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>DEF<bdo "
760       "dir=ltr>abc|</bdo></bdo>ghi</bdo></div>");
761   const PositionWithAffinity position_with_affinity(position,
762                                                     TextAffinity::kDownstream);
763   EXPECT_EQ(PhysicalRect(210, 0, 1, 10),
764             LocalCaretRectOfPosition(position_with_affinity).rect);
765 }
766 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterThreeNestedRuns)767 TEST_P(ParameterizedLocalCaretRectBidiTest,
768        InRtlBlockLtrBaseRunAfterThreeNestedRuns) {
769   // Sample: G H I d e f A B C|j k l
770   // Bidi:   3 3 3 4 4 4 5 5 5 2 2 2
771   // Visual:|d e f C B A I H G j k l
772   LoadAhem();
773   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
774   const Position position = SetCaretTextToBody(
775       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>GHI<bdo dir=ltr>def<bdo "
776       "dir=rtl>ABC</bdo></bdo></bdo>|jkl</bdo></div>");
777   const PositionWithAffinity position_with_affinity(position,
778                                                     TextAffinity::kDownstream);
779   EXPECT_EQ(PhysicalRect(180, 0, 1, 10),
780             LocalCaretRectOfPosition(position_with_affinity).rect);
781 }
782 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterThreeNestedRunsAtDeepPosition)783 TEST_P(ParameterizedLocalCaretRectBidiTest,
784        InRtlBlockLtrBaseRunAfterThreeNestedRunsAtDeepPosition) {
785   // Sample: G H I d e f A B C|j k l
786   // Bidi:   3 3 3 4 4 4 5 5 5 2 2 2
787   // Visual:|d e f C B A I H G j k l
788   LoadAhem();
789   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
790   const Position position = SetCaretTextToBody(
791       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>GHI<bdo dir=ltr>def<bdo "
792       "dir=rtl>ABC|</bdo></bdo></bdo>jkl</bdo></div>");
793   const PositionWithAffinity position_with_affinity(position,
794                                                     TextAffinity::kDownstream);
795   EXPECT_EQ(PhysicalRect(180, 0, 1, 10),
796             LocalCaretRectOfPosition(position_with_affinity).rect);
797 }
798 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterFourNestedRuns)799 TEST_P(ParameterizedLocalCaretRectBidiTest,
800        InRtlBlockLtrBaseRunAfterFourNestedRuns) {
801   // Sample: J K L g h i D E F a b c|m n o
802   // Bidi:   3 3 3 4 4 4 5 5 5 6 6 6 2 2 2
803   // Visual:|g h i a b c F E D L K J m n o
804   LoadAhem();
805   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
806   const Position position = SetCaretTextToBody(
807       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>JKL<bdo dir=ltr>ghi<bdo "
808       "dir=rtl>DEF<bdo dir=ltr>abc</bdo></bdo></bdo></bdo>|mno</bdo></div>");
809   const PositionWithAffinity position_with_affinity(position,
810                                                     TextAffinity::kDownstream);
811   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
812   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(180, 0, 1, 10)
813                               : PhysicalRect(150, 0, 1, 10),
814             LocalCaretRectOfPosition(position_with_affinity).rect);
815 }
816 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunAfterFourNestedRunsAtDeepPosition)817 TEST_P(ParameterizedLocalCaretRectBidiTest,
818        InRtlBlockLtrBaseRunAfterFourNestedRunsAtDeepPosition) {
819   // Sample: J K L g h i D E F a b c|m n o
820   // Bidi:   3 3 3 4 4 4 5 5 5 6 6 6 2 2 2
821   // Visual:|g h i a b c F E D L K J m n o
822   LoadAhem();
823   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
824   const Position position = SetCaretTextToBody(
825       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>JKL<bdo dir=ltr>ghi<bdo "
826       "dir=rtl>DEF<bdo dir=ltr>abc|</bdo></bdo></bdo></bdo>mno</bdo></div>");
827   const PositionWithAffinity position_with_affinity(position,
828                                                     TextAffinity::kDownstream);
829   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
830   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(180, 0, 1, 10)
831                               : PhysicalRect(150, 0, 1, 10),
832             LocalCaretRectOfPosition(position_with_affinity).rect);
833 }
834 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeRtlRunTouchingLineBoundary)835 TEST_P(ParameterizedLocalCaretRectBidiTest,
836        InRtlBlockLtrBaseRunBeforeRtlRunTouchingLineBoundary) {
837   // Sample: d e f|A B C
838   // Bidi:   2 2 2 3 3 3
839   // Visual: d e f C B A|
840   LoadAhem();
841   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
842   const Position position = SetCaretTextToBody(
843       "<div dir=rtl><bdo dir=ltr>def|<bdo dir=rtl>ABC</bdo></bdo></div>");
844   const PositionWithAffinity position_with_affinity(position,
845                                                     TextAffinity::kDownstream);
846   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
847             LocalCaretRectOfPosition(position_with_affinity).rect);
848 }
849 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeRtlRun)850 TEST_P(ParameterizedLocalCaretRectBidiTest, InRtlBlockLtrBaseRunBeforeRtlRun) {
851   // Sample: d e f|A B C g h i
852   // Bidi:   2 2 2 3 3 3 2 2 2
853   // Visual: d e f C B A|g h i
854   LoadAhem();
855   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
856   const Position position = SetCaretTextToBody(
857       "<div dir=rtl><bdo dir=ltr>def|<bdo dir=rtl>ABC</bdo>ghi</bdo></div>");
858   const PositionWithAffinity position_with_affinity(position,
859                                                     TextAffinity::kDownstream);
860   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
861             LocalCaretRectOfPosition(position_with_affinity).rect);
862 }
863 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeRtlRunTouchingLineBoundaryAtDeepPosition)864 TEST_P(ParameterizedLocalCaretRectBidiTest,
865        InRtlBlockLtrBaseRunBeforeRtlRunTouchingLineBoundaryAtDeepPosition) {
866   // Sample: d e f|A B C
867   // Bidi:   2 2 2 3 3 3
868   // Visual: d e f C B A|
869   LoadAhem();
870   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
871   const Position position = SetCaretTextToBody(
872       "<div dir=rtl><bdo dir=ltr>def<bdo dir=rtl>|ABC</bdo></bdo></div>");
873   const PositionWithAffinity position_with_affinity(position,
874                                                     TextAffinity::kDownstream);
875   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
876             LocalCaretRectOfPosition(position_with_affinity).rect);
877 }
878 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeRtlRunAtDeepPosition)879 TEST_P(ParameterizedLocalCaretRectBidiTest,
880        InRtlBlockLtrBaseRunBeforeRtlRunAtDeepPosition) {
881   // Sample: d e f|A B C g h i
882   // Bidi:   2 2 2 3 3 3 2 2 2
883   // Visual: d e f C B A|g h i
884   LoadAhem();
885   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
886   const Position position = SetCaretTextToBody(
887       "<div dir=rtl><bdo dir=ltr>def<bdo dir=rtl>|ABC</bdo>ghi</bdo></div>");
888   const PositionWithAffinity position_with_affinity(position,
889                                                     TextAffinity::kDownstream);
890   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
891             LocalCaretRectOfPosition(position_with_affinity).rect);
892 }
893 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeTwoNestedRuns)894 TEST_P(ParameterizedLocalCaretRectBidiTest,
895        InRtlBlockLtrBaseRunBeforeTwoNestedRuns) {
896   // Sample: g h i|a b c D E F
897   // Bidi:   2 2 2 4 4 4 3 3 3
898   // Visual: g h i F E D a b c|
899   LoadAhem();
900   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
901   const Position position = SetCaretTextToBody(
902       "<div dir=rtl><bdo dir=ltr>ghi|<bdo dir=rtl><bdo "
903       "dir=ltr>abc</bdo>DEF</bdo></bdo></div>");
904   const PositionWithAffinity position_with_affinity(position,
905                                                     TextAffinity::kDownstream);
906   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
907             LocalCaretRectOfPosition(position_with_affinity).rect);
908 }
909 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeTwoNestedRunsAtDeepPosition)910 TEST_P(ParameterizedLocalCaretRectBidiTest,
911        InRtlBlockLtrBaseRunBeforeTwoNestedRunsAtDeepPosition) {
912   // Sample: g h i|a b c D E F
913   // Bidi:   2 2 2 4 4 4 3 3 3
914   // Visual: g h i F E D a b c|
915   LoadAhem();
916   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
917   const Position position = SetCaretTextToBody(
918       "<div dir=rtl><bdo dir=ltr>ghi<bdo dir=rtl><bdo "
919       "dir=ltr>|abc</bdo>DEF</bdo></bdo></div>");
920   const PositionWithAffinity position_with_affinity(position,
921                                                     TextAffinity::kDownstream);
922   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
923             LocalCaretRectOfPosition(position_with_affinity).rect);
924 }
925 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeThreeNestedRuns)926 TEST_P(ParameterizedLocalCaretRectBidiTest,
927        InRtlBlockLtrBaseRunBeforeThreeNestedRuns) {
928   // Sample: j k l|A B C d e f G H I
929   // Bidi:   2 2 2 5 5 5 4 4 4 3 3 3
930   // Visual: j k l I H G C B A d e f|
931   LoadAhem();
932   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
933   const Position position = SetCaretTextToBody(
934       "<div dir=rtl><bdo dir=ltr>jkl|<bdo dir=rtl><bdo dir=ltr><bdo "
935       "dir=rtl>ABC</bdo>def</bdo>GHI</bdo></bdo></div>");
936   const PositionWithAffinity position_with_affinity(position,
937                                                     TextAffinity::kDownstream);
938   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
939             LocalCaretRectOfPosition(position_with_affinity).rect);
940 }
941 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeThreeNestedRunsAtDeepPosition)942 TEST_P(ParameterizedLocalCaretRectBidiTest,
943        InRtlBlockLtrBaseRunBeforeThreeNestedRunsAtDeepPosition) {
944   // Sample: j k l|A B C d e f G H I
945   // Bidi:   2 2 2 5 5 5 4 4 4 3 3 3
946   // Visual: j k l I H G C B A d e f|
947   LoadAhem();
948   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
949   const Position position = SetCaretTextToBody(
950       "<div dir=rtl><bdo dir=ltr>jkl<bdo dir=rtl><bdo dir=ltr><bdo "
951       "dir=rtl>|ABC</bdo>def</bdo>GHI</bdo></bdo></div>");
952   const PositionWithAffinity position_with_affinity(position,
953                                                     TextAffinity::kDownstream);
954   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
955             LocalCaretRectOfPosition(position_with_affinity).rect);
956 }
957 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeFourNestedRuns)958 TEST_P(ParameterizedLocalCaretRectBidiTest,
959        InRtlBlockLtrBaseRunBeforeFourNestedRuns) {
960   // Sample: m n o|a b c D E F g h i J K L
961   // Bidi:   2 2 2 6 6 6 5 5 5 4 4 4 3 3 3
962   // Visual: m n o L K J F E D a b c|g h i
963   LoadAhem();
964   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
965   const Position position = SetCaretTextToBody(
966       "<div dir=rtl><bdo dir=ltr>mno|<bdo dir=rtl><bdo dir=ltr><bdo "
967       "dir=rtl><bdo dir=ltr>abc</bdo>DEF</bdo>ghi</bdo>JKL</bdo></bdo></div>");
968   const PositionWithAffinity position_with_affinity(position,
969                                                     TextAffinity::kDownstream);
970   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
971   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(299, 0, 1, 10)
972                               : PhysicalRect(270, 0, 1, 10),
973             LocalCaretRectOfPosition(position_with_affinity).rect);
974 }
975 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLtrBaseRunBeforeFourNestedRunsAtDeepPosition)976 TEST_P(ParameterizedLocalCaretRectBidiTest,
977        InRtlBlockLtrBaseRunBeforeFourNestedRunsAtDeepPosition) {
978   // Sample: m n o|a b c D E F g h i J K L
979   // Bidi:   2 2 2 6 6 6 5 5 5 4 4 4 3 3 3
980   // Visual: m n o L K J F E D a b c|g h i
981   LoadAhem();
982   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
983   const Position position = SetCaretTextToBody(
984       "<div dir=rtl><bdo dir=ltr>mno<bdo dir=rtl><bdo dir=ltr><bdo "
985       "dir=rtl><bdo dir=ltr>|abc</bdo>DEF</bdo>ghi</bdo>JKL</bdo></bdo></div>");
986   const PositionWithAffinity position_with_affinity(position,
987                                                     TextAffinity::kDownstream);
988   // TODO(xiaochengh): Decide if the behavior difference is worth to fix.
989   EXPECT_EQ(LayoutNGEnabled() ? PhysicalRect(299, 0, 1, 10)
990                               : PhysicalRect(270, 0, 1, 10),
991             LocalCaretRectOfPosition(position_with_affinity).rect);
992 }
993 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterLtrRunTouchingLineBoundary)994 TEST_P(ParameterizedLocalCaretRectBidiTest,
995        InRtlBlockRtlBaseRunAfterLtrRunTouchingLineBoundary) {
996   // Sample: a b c|D E F
997   // Bidi:   2 2 2 1 1 1
998   // Visual: F E D|a b c
999   LoadAhem();
1000   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1001   const Position position = SetCaretTextToBody(
1002       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>abc</bdo>|DEF</bdo></div>");
1003   const PositionWithAffinity position_with_affinity(position,
1004                                                     TextAffinity::kDownstream);
1005   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1006             LocalCaretRectOfPosition(position_with_affinity).rect);
1007 }
1008 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterLtrRun)1009 TEST_P(ParameterizedLocalCaretRectBidiTest, InRtlBlockRtlBaseRunAfterLtrRun) {
1010   // Sample: G H I a b c|D E F
1011   // Bidi:   1 1 1 2 2 2 1 1 1
1012   // Visual: F E D|a b c I H G
1013   LoadAhem();
1014   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1015   const Position position = SetCaretTextToBody(
1016       "<div dir=rtl><bdo dir=rtl>GHI<bdo dir=ltr>abc</bdo>|DEF</bdo></div>");
1017   const PositionWithAffinity position_with_affinity(position,
1018                                                     TextAffinity::kDownstream);
1019   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1020             LocalCaretRectOfPosition(position_with_affinity).rect);
1021 }
1022 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterLtrRunTouchingLineBoundaryAtDeepPosition)1023 TEST_P(ParameterizedLocalCaretRectBidiTest,
1024        InRtlBlockRtlBaseRunAfterLtrRunTouchingLineBoundaryAtDeepPosition) {
1025   // Sample: a b c|D E F
1026   // Bidi:   2 2 2 1 1 1
1027   // Visual: F E D|a b c
1028   LoadAhem();
1029   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1030   const Position position = SetCaretTextToBody(
1031       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>abc|</bdo>DEF</bdo></div>");
1032   const PositionWithAffinity position_with_affinity(position,
1033                                                     TextAffinity::kDownstream);
1034   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1035             LocalCaretRectOfPosition(position_with_affinity).rect);
1036 }
1037 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterLtrRunAtDeepPosition)1038 TEST_P(ParameterizedLocalCaretRectBidiTest,
1039        InRtlBlockRtlBaseRunAfterLtrRunAtDeepPosition) {
1040   // Sample: G H I a b c|D E F
1041   // Bidi:   1 1 1 2 2 2 1 1 1
1042   // Visual: F E D|a b c I H G
1043   LoadAhem();
1044   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1045   const Position position = SetCaretTextToBody(
1046       "<div dir=rtl><bdo dir=rtl>GHI<bdo dir=ltr>abc|</bdo>DEF</bdo></div>");
1047   const PositionWithAffinity position_with_affinity(position,
1048                                                     TextAffinity::kDownstream);
1049   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1050             LocalCaretRectOfPosition(position_with_affinity).rect);
1051 }
1052 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterTwoNestedRuns)1053 TEST_P(ParameterizedLocalCaretRectBidiTest,
1054        InRtlBlockRtlBaseRunAfterTwoNestedRuns) {
1055   // Sample: d e f A B C|G H I
1056   // Bidi:   2 2 2 3 3 3 1 1 1
1057   // Visual: I H G|d e f C B A
1058   LoadAhem();
1059   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1060   const Position position = SetCaretTextToBody(
1061       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>def<bdo "
1062       "dir=rtl>ABC</bdo></bdo>|GHI</bdo></div>");
1063   const PositionWithAffinity position_with_affinity(position,
1064                                                     TextAffinity::kDownstream);
1065   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1066             LocalCaretRectOfPosition(position_with_affinity).rect);
1067 }
1068 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterTwoNestedRunsAtDeepPosition)1069 TEST_P(ParameterizedLocalCaretRectBidiTest,
1070        InRtlBlockRtlBaseRunAfterTwoNestedRunsAtDeepPosition) {
1071   // Sample: d e f A B C|G H I
1072   // Bidi:   2 2 2 3 3 3 1 1 1
1073   // Visual: I H G|d e f C B A
1074   LoadAhem();
1075   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1076   const Position position = SetCaretTextToBody(
1077       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>def<bdo "
1078       "dir=rtl>ABC|</bdo></bdo>GHI</bdo></div>");
1079   const PositionWithAffinity position_with_affinity(position,
1080                                                     TextAffinity::kDownstream);
1081   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1082             LocalCaretRectOfPosition(position_with_affinity).rect);
1083 }
1084 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterThreeNestedRuns)1085 TEST_P(ParameterizedLocalCaretRectBidiTest,
1086        InRtlBlockRtlBaseRunAfterThreeNestedRuns) {
1087   // Sample: g h i D E F a b c|J K L
1088   // Bidi:   2 2 2 3 3 3 4 4 4 1 1 1
1089   // Visual: L K J|g h i a b c F E D
1090   LoadAhem();
1091   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1092   const Position position = SetCaretTextToBody(
1093       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>ghi<bdo dir=rtl>DEF<bdo "
1094       "dir=ltr>abc</bdo></bdo></bdo>|JKL</bdo></div>");
1095   const PositionWithAffinity position_with_affinity(position,
1096                                                     TextAffinity::kDownstream);
1097   EXPECT_EQ(PhysicalRect(210, 0, 1, 10),
1098             LocalCaretRectOfPosition(position_with_affinity).rect);
1099 }
1100 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterThreeNestedRunsAtDeepPosition)1101 TEST_P(ParameterizedLocalCaretRectBidiTest,
1102        InRtlBlockRtlBaseRunAfterThreeNestedRunsAtDeepPosition) {
1103   // Sample: g h i D E F a b c|J K L
1104   // Bidi:   2 2 2 3 3 3 4 4 4 1 1 1
1105   // Visual: L K J|g h i a b c F E D
1106   LoadAhem();
1107   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1108   const Position position = SetCaretTextToBody(
1109       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>ghi<bdo dir=rtl>DEF<bdo "
1110       "dir=ltr>abc|</bdo></bdo></bdo>JKL</bdo></div>");
1111   const PositionWithAffinity position_with_affinity(position,
1112                                                     TextAffinity::kDownstream);
1113   EXPECT_EQ(PhysicalRect(210, 0, 1, 10),
1114             LocalCaretRectOfPosition(position_with_affinity).rect);
1115 }
1116 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterFourNestedRuns)1117 TEST_P(ParameterizedLocalCaretRectBidiTest,
1118        InRtlBlockRtlBaseRunAfterFourNestedRuns) {
1119   // Sample: j k l G H I d e f A B C|M N O
1120   // Bidi:   2 2 2 3 3 3 4 4 4 5 5 5 1 1 1
1121   // Visual: O N M|j k l d e f C B A I H G
1122   LoadAhem();
1123   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1124   const Position position = SetCaretTextToBody(
1125       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>jkl<bdo dir=rtl>GHI<bdo "
1126       "dir=ltr>def<bdo dir=rtl>ABC</bdo></bdo></bdo></bdo>|MNO</bdo></div>");
1127   const PositionWithAffinity position_with_affinity(position,
1128                                                     TextAffinity::kDownstream);
1129   EXPECT_EQ(PhysicalRect(180, 0, 1, 10),
1130             LocalCaretRectOfPosition(position_with_affinity).rect);
1131 }
1132 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunAfterFourNestedRunsAtDeepPosition)1133 TEST_P(ParameterizedLocalCaretRectBidiTest,
1134        InRtlBlockRtlBaseRunAfterFourNestedRunsAtDeepPosition) {
1135   // Sample: j k l G H I d e f A B C|M N O
1136   // Bidi:   2 2 2 3 3 3 4 4 4 5 5 5 1 1 1
1137   // Visual: O N M|j k l d e f C B A I H G
1138   LoadAhem();
1139   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1140   const Position position = SetCaretTextToBody(
1141       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>jkl<bdo dir=rtl>GHI<bdo "
1142       "dir=ltr>def<bdo dir=rtl>ABC|</bdo></bdo></bdo></bdo>MNO</bdo></div>");
1143   const PositionWithAffinity position_with_affinity(position,
1144                                                     TextAffinity::kDownstream);
1145   EXPECT_EQ(PhysicalRect(180, 0, 1, 10),
1146             LocalCaretRectOfPosition(position_with_affinity).rect);
1147 }
1148 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeLtrRunTouchingLineBoundary)1149 TEST_P(ParameterizedLocalCaretRectBidiTest,
1150        InRtlBlockRtlBaseRunBeforeLtrRunTouchingLineBoundary) {
1151   // Sample: D E F|a b c
1152   // Bidi:   1 1 1 2 2 2
1153   // Visual: a b c|F E D
1154   LoadAhem();
1155   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1156   const Position position = SetCaretTextToBody(
1157       "<div dir=rtl><bdo dir=rtl>DEF|<bdo dir=ltr>abc</bdo></bdo></div>");
1158   const PositionWithAffinity position_with_affinity(position,
1159                                                     TextAffinity::kDownstream);
1160   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1161             LocalCaretRectOfPosition(position_with_affinity).rect);
1162 }
1163 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeLtrRun)1164 TEST_P(ParameterizedLocalCaretRectBidiTest, InRtlBlockRtlBaseRunBeforeLtrRun) {
1165   // Sample: D E F|a b c G H I
1166   // Bidi:   1 1 1 2 2 2 1 1 1
1167   // Visual: I H G a b c|F E D
1168   LoadAhem();
1169   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1170   const Position position = SetCaretTextToBody(
1171       "<div dir=rtl><bdo dir=rtl>DEF|<bdo dir=ltr>abc</bdo>GHI</bdo></div>");
1172   const PositionWithAffinity position_with_affinity(position,
1173                                                     TextAffinity::kDownstream);
1174   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1175             LocalCaretRectOfPosition(position_with_affinity).rect);
1176 }
1177 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeLtrRunTouchingLineBoundaryAtDeepPosition)1178 TEST_P(ParameterizedLocalCaretRectBidiTest,
1179        InRtlBlockRtlBaseRunBeforeLtrRunTouchingLineBoundaryAtDeepPosition) {
1180   // Sample: D E F|a b c
1181   // Bidi:   1 1 1 2 2 2
1182   // Visual: a b c|F E D
1183   LoadAhem();
1184   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1185   const Position position = SetCaretTextToBody(
1186       "<div dir=rtl><bdo dir=rtl>DEF<bdo dir=ltr>|abc</bdo></bdo></div>");
1187   const PositionWithAffinity position_with_affinity(position,
1188                                                     TextAffinity::kDownstream);
1189   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1190             LocalCaretRectOfPosition(position_with_affinity).rect);
1191 }
1192 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeLtrRunAtDeepPosition)1193 TEST_P(ParameterizedLocalCaretRectBidiTest,
1194        InRtlBlockRtlBaseRunBeforeLtrRunAtDeepPosition) {
1195   // Sample: D E F|a b c G H I
1196   // Bidi:   1 1 1 2 2 2 1 1 1
1197   // Visual: I H G a b c|F E D
1198   LoadAhem();
1199   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1200   const Position position = SetCaretTextToBody(
1201       "<div dir=rtl><bdo dir=rtl>DEF<bdo dir=ltr>|abc</bdo>GHI</bdo></div>");
1202   const PositionWithAffinity position_with_affinity(position,
1203                                                     TextAffinity::kDownstream);
1204   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1205             LocalCaretRectOfPosition(position_with_affinity).rect);
1206 }
1207 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeTwoNestedRuns)1208 TEST_P(ParameterizedLocalCaretRectBidiTest,
1209        InRtlBlockRtlBaseRunBeforeTwoNestedRuns) {
1210   // Sample: G H I|A B C d e f
1211   // Bidi:   1 1 1 3 3 3 2 2 2
1212   // Visual: C B A d e f|I H G
1213   LoadAhem();
1214   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1215   const Position position = SetCaretTextToBody(
1216       "<div dir=rtl><bdo dir=rtl>GHI|<bdo dir=ltr><bdo "
1217       "dir=rtl>ABC</bdo>def</bdo></bdo></div>");
1218   const PositionWithAffinity position_with_affinity(position,
1219                                                     TextAffinity::kDownstream);
1220   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1221             LocalCaretRectOfPosition(position_with_affinity).rect);
1222 }
1223 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeTwoNestedRunsAtDeepPosition)1224 TEST_P(ParameterizedLocalCaretRectBidiTest,
1225        InRtlBlockRtlBaseRunBeforeTwoNestedRunsAtDeepPosition) {
1226   // Sample: G H I|A B C d e f
1227   // Bidi:   1 1 1 3 3 3 2 2 2
1228   // Visual: C B A d e f|I H G
1229   LoadAhem();
1230   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1231   const Position position = SetCaretTextToBody(
1232       "<div dir=rtl><bdo dir=rtl>GHI<bdo dir=ltr><bdo "
1233       "dir=rtl>|ABC</bdo>def</bdo></bdo></div>");
1234   const PositionWithAffinity position_with_affinity(position,
1235                                                     TextAffinity::kDownstream);
1236   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1237             LocalCaretRectOfPosition(position_with_affinity).rect);
1238 }
1239 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeThreeNestedRuns)1240 TEST_P(ParameterizedLocalCaretRectBidiTest,
1241        InRtlBlockRtlBaseRunBeforeThreeNestedRuns) {
1242   // Sample: J K L|a b c D E F g h i
1243   // Bidi:   1 1 1 4 4 4 3 3 3 2 2 2
1244   // Visual: F E D a b c|g h i L K J
1245   LoadAhem();
1246   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1247   const Position position = SetCaretTextToBody(
1248       "<div dir=rtl><bdo dir=rtl>JKL|<bdo dir=ltr><bdo dir=rtl><bdo "
1249       "dir=ltr>abc</bdo>DEF</bdo>ghi</bdo></bdo></div>");
1250   const PositionWithAffinity position_with_affinity(position,
1251                                                     TextAffinity::kDownstream);
1252   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1253             LocalCaretRectOfPosition(position_with_affinity).rect);
1254 }
1255 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeThreeNestedRunsAtDeepPosition)1256 TEST_P(ParameterizedLocalCaretRectBidiTest,
1257        InRtlBlockRtlBaseRunBeforeThreeNestedRunsAtDeepPosition) {
1258   // Sample: J K L|a b c D E F g h i
1259   // Bidi:   1 1 1 4 4 4 3 3 3 2 2 2
1260   // Visual: F E D a b c|g h i L K J
1261   LoadAhem();
1262   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1263   const Position position = SetCaretTextToBody(
1264       "<div dir=rtl><bdo dir=rtl>JKL<bdo dir=ltr><bdo dir=rtl><bdo "
1265       "dir=ltr>|abc</bdo>DEF</bdo>ghi</bdo></bdo></div>");
1266   const PositionWithAffinity position_with_affinity(position,
1267                                                     TextAffinity::kDownstream);
1268   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1269             LocalCaretRectOfPosition(position_with_affinity).rect);
1270 }
1271 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeFourNestedRuns)1272 TEST_P(ParameterizedLocalCaretRectBidiTest,
1273        InRtlBlockRtlBaseRunBeforeFourNestedRuns) {
1274   // Sample: M N O|A B C d e f G H I j k l
1275   // Bidi:   1 1 1 5 5 5 4 4 4 3 3 3 2 2 2
1276   // Visual: I H G C B A d e f|j k l O N M
1277   LoadAhem();
1278   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1279   const Position position = SetCaretTextToBody(
1280       "<div dir=rtl><bdo dir=rtl>MNO|<bdo dir=ltr><bdo dir=rtl><bdo "
1281       "dir=ltr><bdo dir=rtl>ABC</bdo>def</bdo>GHI</bdo>jkl</bdo></bdo></div>");
1282   const PositionWithAffinity position_with_affinity(position,
1283                                                     TextAffinity::kDownstream);
1284   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1285             LocalCaretRectOfPosition(position_with_affinity).rect);
1286 }
1287 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockRtlBaseRunBeforeFourNestedRunsAtDeepPosition)1288 TEST_P(ParameterizedLocalCaretRectBidiTest,
1289        InRtlBlockRtlBaseRunBeforeFourNestedRunsAtDeepPosition) {
1290   // Sample: M N O|A B C d e f G H I j k l
1291   // Bidi:   1 1 1 5 5 5 4 4 4 3 3 3 2 2 2
1292   // Visual: I H G C B A d e f|j k l O N M
1293   LoadAhem();
1294   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1295   const Position position = SetCaretTextToBody(
1296       "<div dir=rtl><bdo dir=rtl>MNO<bdo dir=ltr><bdo dir=rtl><bdo "
1297       "dir=ltr><bdo dir=rtl>|ABC</bdo>def</bdo>GHI</bdo>jkl</bdo></bdo></div>");
1298   const PositionWithAffinity position_with_affinity(position,
1299                                                     TextAffinity::kDownstream);
1300   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1301             LocalCaretRectOfPosition(position_with_affinity).rect);
1302 }
1303 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineBeginLtrBaseRunWithTwoNestedRuns)1304 TEST_P(ParameterizedLocalCaretRectBidiTest,
1305        InLtrBlockLineBeginLtrBaseRunWithTwoNestedRuns) {
1306   // Sample:|A B C d e f
1307   // Bidi:   1 1 1 0 0 0
1308   // Visual:|C B A d e f
1309   LoadAhem();
1310   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1311   const Position position = SetCaretTextToBody(
1312       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl>|ABC</bdo>def</bdo></div>");
1313   const PositionWithAffinity position_with_affinity(position,
1314                                                     TextAffinity::kDownstream);
1315   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
1316             LocalCaretRectOfPosition(position_with_affinity).rect);
1317 }
1318 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineBeginLtrBaseRunWithThreeNestedRuns)1319 TEST_P(ParameterizedLocalCaretRectBidiTest,
1320        InLtrBlockLineBeginLtrBaseRunWithThreeNestedRuns) {
1321   // Sample:|a b c D E F g h i
1322   // Bidi:   2 2 2 1 1 1 0 0 0
1323   // Visual:|F E D a b c g h i
1324   LoadAhem();
1325   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1326   const Position position = SetCaretTextToBody(
1327       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl><bdo "
1328       "dir=ltr>|abc</bdo>DEF</bdo>ghi</bdo></div>");
1329   const PositionWithAffinity position_with_affinity(position,
1330                                                     TextAffinity::kDownstream);
1331   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
1332             LocalCaretRectOfPosition(position_with_affinity).rect);
1333 }
1334 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineBeginLtrBaseRunWithFourNestedRuns)1335 TEST_P(ParameterizedLocalCaretRectBidiTest,
1336        InLtrBlockLineBeginLtrBaseRunWithFourNestedRuns) {
1337   // Sample:|A B C d e f G H I j k l
1338   // Bidi:   3 3 3 2 2 2 1 1 1 0 0 0
1339   // Visual: I H G|C B A d e f j k l
1340   LoadAhem();
1341   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1342   const Position position = SetCaretTextToBody(
1343       "<div dir=ltr><bdo dir=ltr><bdo dir=rtl><bdo dir=ltr><bdo "
1344       "dir=rtl>|ABC</bdo>def</bdo>GHI</bdo>jkl</bdo></div>");
1345   const PositionWithAffinity position_with_affinity(position,
1346                                                     TextAffinity::kDownstream);
1347   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
1348             LocalCaretRectOfPosition(position_with_affinity).rect);
1349 }
1350 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineEndLtrBaseRunWithTwoNestedRuns)1351 TEST_P(ParameterizedLocalCaretRectBidiTest,
1352        InLtrBlockLineEndLtrBaseRunWithTwoNestedRuns) {
1353   // Sample: d e f A B C|
1354   // Bidi:   0 0 0 1 1 1
1355   // Visual: d e f C B A|
1356   LoadAhem();
1357   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1358   const Position position = SetCaretTextToBody(
1359       "<div dir=ltr><bdo dir=ltr>def<bdo dir=rtl>ABC|</bdo></bdo></div>");
1360   const PositionWithAffinity position_with_affinity(position,
1361                                                     TextAffinity::kDownstream);
1362   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
1363             LocalCaretRectOfPosition(position_with_affinity).rect);
1364 }
1365 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineEndLtrBaseRunWithThreeNestedRuns)1366 TEST_P(ParameterizedLocalCaretRectBidiTest,
1367        InLtrBlockLineEndLtrBaseRunWithThreeNestedRuns) {
1368   // Sample: g h i D E F a b c|
1369   // Bidi:   0 0 0 1 1 1 2 2 2
1370   // Visual: g h i a b c F E D|
1371   LoadAhem();
1372   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1373   const Position position = SetCaretTextToBody(
1374       "<div dir=ltr><bdo dir=ltr>ghi<bdo dir=rtl>DEF<bdo "
1375       "dir=ltr>abc|</bdo></bdo></bdo></div>");
1376   const PositionWithAffinity position_with_affinity(position,
1377                                                     TextAffinity::kDownstream);
1378   EXPECT_EQ(PhysicalRect(90, 0, 1, 10),
1379             LocalCaretRectOfPosition(position_with_affinity).rect);
1380 }
1381 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineEndLtrBaseRunWithFourNestedRuns)1382 TEST_P(ParameterizedLocalCaretRectBidiTest,
1383        InLtrBlockLineEndLtrBaseRunWithFourNestedRuns) {
1384   // Sample: j k l G H I d e f A B C|
1385   // Bidi:   0 0 0 1 1 1 2 2 2 3 3 3
1386   // Visual: j k l d e f C B A|I H G
1387   LoadAhem();
1388   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1389   const Position position = SetCaretTextToBody(
1390       "<div dir=ltr><bdo dir=ltr>jkl<bdo dir=rtl>GHI<bdo dir=ltr>def<bdo "
1391       "dir=rtl>ABC|</bdo></bdo></bdo></bdo></div>");
1392   const PositionWithAffinity position_with_affinity(position,
1393                                                     TextAffinity::kDownstream);
1394   EXPECT_EQ(PhysicalRect(90, 0, 1, 10),
1395             LocalCaretRectOfPosition(position_with_affinity).rect);
1396 }
1397 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineBeginWithRtlRunOnly)1398 TEST_P(ParameterizedLocalCaretRectBidiTest, InLtrBlockLineBeginWithRtlRunOnly) {
1399   // Sample:|A B C
1400   // Bidi:   1 1 1
1401   // Visual:|C B A
1402   LoadAhem();
1403   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1404   const Position position =
1405       SetCaretTextToBody("<div dir=ltr><bdo dir=rtl>|ABC</bdo></div>");
1406   const PositionWithAffinity position_with_affinity(position,
1407                                                     TextAffinity::kDownstream);
1408   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
1409             LocalCaretRectOfPosition(position_with_affinity).rect);
1410 }
1411 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineBeginRtlBaseRunWithTwoNestedRuns)1412 TEST_P(ParameterizedLocalCaretRectBidiTest,
1413        InLtrBlockLineBeginRtlBaseRunWithTwoNestedRuns) {
1414   // Sample:|a b c D E F
1415   // Bidi:   2 2 2 1 1 1
1416   // Visual:|F E D a b c
1417   LoadAhem();
1418   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1419   const Position position = SetCaretTextToBody(
1420       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr>|abc</bdo>DEF</bdo></div>");
1421   const PositionWithAffinity position_with_affinity(position,
1422                                                     TextAffinity::kDownstream);
1423   EXPECT_EQ(PhysicalRect(0, 0, 1, 10),
1424             LocalCaretRectOfPosition(position_with_affinity).rect);
1425 }
1426 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineBeginRtlBaseRunWithThreeNestedRuns)1427 TEST_P(ParameterizedLocalCaretRectBidiTest,
1428        InLtrBlockLineBeginRtlBaseRunWithThreeNestedRuns) {
1429   // Sample:|A B C d e f G H I
1430   // Bidi:   3 3 3 2 2 2 1 1 1
1431   // Visual: I H G|C B A d e f
1432   LoadAhem();
1433   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1434   const Position position = SetCaretTextToBody(
1435       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr><bdo "
1436       "dir=rtl>|ABC</bdo>def</bdo>GHI</bdo></div>");
1437   const PositionWithAffinity position_with_affinity(position,
1438                                                     TextAffinity::kDownstream);
1439   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
1440             LocalCaretRectOfPosition(position_with_affinity).rect);
1441 }
1442 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineBeginRtlBaseRunWithFourNestedRuns)1443 TEST_P(ParameterizedLocalCaretRectBidiTest,
1444        InLtrBlockLineBeginRtlBaseRunWithFourNestedRuns) {
1445   // Sample:|a b c D E F g h i J K L
1446   // Bidi:   4 4 4 3 3 3 2 2 2 1 1 1
1447   // Visual: L K J|F E D a b c g h i
1448   LoadAhem();
1449   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1450   const Position position = SetCaretTextToBody(
1451       "<div dir=ltr><bdo dir=rtl><bdo dir=ltr><bdo dir=rtl><bdo "
1452       "dir=ltr>|abc</bdo>DEF</bdo>ghi</bdo>JKL</bdo></div>");
1453   const PositionWithAffinity position_with_affinity(position,
1454                                                     TextAffinity::kDownstream);
1455   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
1456             LocalCaretRectOfPosition(position_with_affinity).rect);
1457 }
1458 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineEndWithRtlRunOnly)1459 TEST_P(ParameterizedLocalCaretRectBidiTest, InLtrBlockLineEndWithRtlRunOnly) {
1460   // Sample: A B C|
1461   // Bidi:   1 1 1
1462   // Visual: C B A|
1463   LoadAhem();
1464   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1465   const Position position =
1466       SetCaretTextToBody("<div dir=ltr><bdo dir=rtl>ABC|</bdo></div>");
1467   const PositionWithAffinity position_with_affinity(position,
1468                                                     TextAffinity::kDownstream);
1469   EXPECT_EQ(PhysicalRect(30, 0, 1, 10),
1470             LocalCaretRectOfPosition(position_with_affinity).rect);
1471 }
1472 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineEndRtlBaseRunWithTwoNestedRuns)1473 TEST_P(ParameterizedLocalCaretRectBidiTest,
1474        InLtrBlockLineEndRtlBaseRunWithTwoNestedRuns) {
1475   // Sample: D E F a b c|
1476   // Bidi:   1 1 1 2 2 2
1477   // Visual: a b c F E D|
1478   LoadAhem();
1479   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1480   const Position position = SetCaretTextToBody(
1481       "<div dir=ltr><bdo dir=rtl>DEF<bdo dir=ltr>abc|</bdo></bdo></div>");
1482   const PositionWithAffinity position_with_affinity(position,
1483                                                     TextAffinity::kDownstream);
1484   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
1485             LocalCaretRectOfPosition(position_with_affinity).rect);
1486 }
1487 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineEndRtlBaseRunWithThreeNestedRuns)1488 TEST_P(ParameterizedLocalCaretRectBidiTest,
1489        InLtrBlockLineEndRtlBaseRunWithThreeNestedRuns) {
1490   // Sample: G H I d e f A B C|
1491   // Bidi:   1 1 1 2 2 2 3 3 3
1492   // Visual: d e f C B A|I H G
1493   LoadAhem();
1494   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1495   const Position position = SetCaretTextToBody(
1496       "<div dir=ltr><bdo dir=rtl>GHI<bdo dir=ltr>def<bdo "
1497       "dir=rtl>ABC|</bdo></bdo></bdo></div>");
1498   const PositionWithAffinity position_with_affinity(position,
1499                                                     TextAffinity::kDownstream);
1500   EXPECT_EQ(PhysicalRect(60, 0, 1, 10),
1501             LocalCaretRectOfPosition(position_with_affinity).rect);
1502 }
1503 
TEST_P(ParameterizedLocalCaretRectBidiTest,InLtrBlockLineEndRtlBaseRunWithFourNestedRuns)1504 TEST_P(ParameterizedLocalCaretRectBidiTest,
1505        InLtrBlockLineEndRtlBaseRunWithFourNestedRuns) {
1506   // Sample: J K L g h i D E F a b c|
1507   // Bidi:   1 1 1 2 2 2 3 3 3 4 4 4
1508   // Visual: g h i a b c F E D|L K J
1509   LoadAhem();
1510   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1511   const Position position = SetCaretTextToBody(
1512       "<div dir=ltr><bdo dir=rtl>JKL<bdo dir=ltr>ghi<bdo dir=rtl>DEF<bdo "
1513       "dir=ltr>abc|</bdo></bdo></bdo></bdo></div>");
1514   const PositionWithAffinity position_with_affinity(position,
1515                                                     TextAffinity::kDownstream);
1516   EXPECT_EQ(PhysicalRect(90, 0, 1, 10),
1517             LocalCaretRectOfPosition(position_with_affinity).rect);
1518 }
1519 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineBeginWithLtrRunOnly)1520 TEST_P(ParameterizedLocalCaretRectBidiTest, InRtlBlockLineBeginWithLtrRunOnly) {
1521   // Sample:|a b c
1522   // Bidi:   2 2 2
1523   // Visual: a b c|
1524   LoadAhem();
1525   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1526   const Position position =
1527       SetCaretTextToBody("<div dir=rtl><bdo dir=ltr>|abc</bdo></div>");
1528   const PositionWithAffinity position_with_affinity(position,
1529                                                     TextAffinity::kDownstream);
1530   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
1531             LocalCaretRectOfPosition(position_with_affinity).rect);
1532 }
1533 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineBeginLtrBaseRunWithTwoNestedRuns)1534 TEST_P(ParameterizedLocalCaretRectBidiTest,
1535        InRtlBlockLineBeginLtrBaseRunWithTwoNestedRuns) {
1536   // Sample:|A B C d e f
1537   // Bidi:   3 3 3 2 2 2
1538   // Visual: C B A d e f|
1539   LoadAhem();
1540   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1541   const Position position = SetCaretTextToBody(
1542       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl>|ABC</bdo>def</bdo></div>");
1543   const PositionWithAffinity position_with_affinity(position,
1544                                                     TextAffinity::kDownstream);
1545   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
1546             LocalCaretRectOfPosition(position_with_affinity).rect);
1547 }
1548 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineBeginLtrBaseRunWithThreeNestedRuns)1549 TEST_P(ParameterizedLocalCaretRectBidiTest,
1550        InRtlBlockLineBeginLtrBaseRunWithThreeNestedRuns) {
1551   // Sample:|a b c D E F g h i
1552   // Bidi:   4 4 4 3 3 3 2 2 2
1553   // Visual: F E D a b c|g h i
1554   LoadAhem();
1555   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1556   const Position position = SetCaretTextToBody(
1557       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl><bdo "
1558       "dir=ltr>|abc</bdo>DEF</bdo>ghi</bdo></div>");
1559   const PositionWithAffinity position_with_affinity(position,
1560                                                     TextAffinity::kDownstream);
1561   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1562             LocalCaretRectOfPosition(position_with_affinity).rect);
1563 }
1564 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineBeginLtrBaseRunWithFourNestedRuns)1565 TEST_P(ParameterizedLocalCaretRectBidiTest,
1566        InRtlBlockLineBeginLtrBaseRunWithFourNestedRuns) {
1567   // Sample:|A B C d e f G H I j k l
1568   // Bidi:   5 5 5 4 4 4 3 3 3 2 2 2
1569   // Visual: I H G C B A d e f|j k l
1570   LoadAhem();
1571   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1572   const Position position = SetCaretTextToBody(
1573       "<div dir=rtl><bdo dir=ltr><bdo dir=rtl><bdo dir=ltr><bdo "
1574       "dir=rtl>|ABC</bdo>def</bdo>GHI</bdo>jkl</bdo></div>");
1575   const PositionWithAffinity position_with_affinity(position,
1576                                                     TextAffinity::kDownstream);
1577   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1578             LocalCaretRectOfPosition(position_with_affinity).rect);
1579 }
1580 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineEndWithLtrRunOnly)1581 TEST_P(ParameterizedLocalCaretRectBidiTest, InRtlBlockLineEndWithLtrRunOnly) {
1582   // Sample: a b c|
1583   // Bidi:   2 2 2
1584   // Visual:|a b c
1585   LoadAhem();
1586   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1587   const Position position =
1588       SetCaretTextToBody("<div dir=rtl><bdo dir=ltr>abc|</bdo></div>");
1589   const PositionWithAffinity position_with_affinity(position,
1590                                                     TextAffinity::kDownstream);
1591   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1592             LocalCaretRectOfPosition(position_with_affinity).rect);
1593 }
1594 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineEndLtrBaseRunWithTwoNestedRuns)1595 TEST_P(ParameterizedLocalCaretRectBidiTest,
1596        InRtlBlockLineEndLtrBaseRunWithTwoNestedRuns) {
1597   // Sample: d e f A B C|
1598   // Bidi:   2 2 2 3 3 3
1599   // Visual:|d e f C B A
1600   LoadAhem();
1601   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1602   const Position position = SetCaretTextToBody(
1603       "<div dir=rtl><bdo dir=ltr>def<bdo dir=rtl>ABC|</bdo></bdo></div>");
1604   const PositionWithAffinity position_with_affinity(position,
1605                                                     TextAffinity::kDownstream);
1606   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1607             LocalCaretRectOfPosition(position_with_affinity).rect);
1608 }
1609 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineEndLtrBaseRunWithThreeNestedRuns)1610 TEST_P(ParameterizedLocalCaretRectBidiTest,
1611        InRtlBlockLineEndLtrBaseRunWithThreeNestedRuns) {
1612   // Sample: g h i D E F a b c|
1613   // Bidi:   2 2 2 3 3 3 4 4 4
1614   // Visual: g h i|a b c F E D
1615   LoadAhem();
1616   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1617   const Position position = SetCaretTextToBody(
1618       "<div dir=rtl><bdo dir=ltr>ghi<bdo dir=rtl>DEF<bdo "
1619       "dir=ltr>abc|</bdo></bdo></bdo></div>");
1620   const PositionWithAffinity position_with_affinity(position,
1621                                                     TextAffinity::kDownstream);
1622   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1623             LocalCaretRectOfPosition(position_with_affinity).rect);
1624 }
1625 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineEndLtrBaseRunWithFourNestedRuns)1626 TEST_P(ParameterizedLocalCaretRectBidiTest,
1627        InRtlBlockLineEndLtrBaseRunWithFourNestedRuns) {
1628   // Sample: j k l G H I d e f A B C|
1629   // Bidi:   2 2 2 3 3 3 4 4 4 5 5 5
1630   // Visual: j k l|d e f C B A I H G
1631   LoadAhem();
1632   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1633   const Position position = SetCaretTextToBody(
1634       "<div dir=rtl><bdo dir=ltr>jkl<bdo dir=rtl>GHI<bdo dir=ltr>def<bdo "
1635       "dir=rtl>ABC|</bdo></bdo></bdo></bdo></div>");
1636   const PositionWithAffinity position_with_affinity(position,
1637                                                     TextAffinity::kDownstream);
1638   EXPECT_EQ(PhysicalRect(210, 0, 1, 10),
1639             LocalCaretRectOfPosition(position_with_affinity).rect);
1640 }
1641 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineBeginRtlBaseRunWithTwoNestedRuns)1642 TEST_P(ParameterizedLocalCaretRectBidiTest,
1643        InRtlBlockLineBeginRtlBaseRunWithTwoNestedRuns) {
1644   // Sample:|a b c D E F
1645   // Bidi:   2 2 2 1 1 1
1646   // Visual: F E D a b c|
1647   LoadAhem();
1648   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1649   const Position position = SetCaretTextToBody(
1650       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr>|abc</bdo>DEF</bdo></div>");
1651   const PositionWithAffinity position_with_affinity(position,
1652                                                     TextAffinity::kDownstream);
1653   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
1654             LocalCaretRectOfPosition(position_with_affinity).rect);
1655 }
1656 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineBeginRtlBaseRunWithThreeNestedRuns)1657 TEST_P(ParameterizedLocalCaretRectBidiTest,
1658        InRtlBlockLineBeginRtlBaseRunWithThreeNestedRuns) {
1659   // Sample:|A B C d e f G H I
1660   // Bidi:   3 3 3 2 2 2 1 1 1
1661   // Visual: I H G C B A d e f|
1662   LoadAhem();
1663   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1664   const Position position = SetCaretTextToBody(
1665       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr><bdo "
1666       "dir=rtl>|ABC</bdo>def</bdo>GHI</bdo></div>");
1667   const PositionWithAffinity position_with_affinity(position,
1668                                                     TextAffinity::kDownstream);
1669   EXPECT_EQ(PhysicalRect(299, 0, 1, 10),
1670             LocalCaretRectOfPosition(position_with_affinity).rect);
1671 }
1672 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineBeginRtlBaseRunWithFourNestedRuns)1673 TEST_P(ParameterizedLocalCaretRectBidiTest,
1674        InRtlBlockLineBeginRtlBaseRunWithFourNestedRuns) {
1675   // Sample:|a b c D E F g h i J K L
1676   // Bidi:   4 4 4 3 3 3 2 2 2 1 1 1
1677   // Visual: L K J F E D a b c|g h i
1678   LoadAhem();
1679   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1680   const Position position = SetCaretTextToBody(
1681       "<div dir=rtl><bdo dir=rtl><bdo dir=ltr><bdo dir=rtl><bdo "
1682       "dir=ltr>|abc</bdo>DEF</bdo>ghi</bdo>JKL</bdo></div>");
1683   const PositionWithAffinity position_with_affinity(position,
1684                                                     TextAffinity::kDownstream);
1685   EXPECT_EQ(PhysicalRect(270, 0, 1, 10),
1686             LocalCaretRectOfPosition(position_with_affinity).rect);
1687 }
1688 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineEndRtlBaseRunWithTwoNestedRuns)1689 TEST_P(ParameterizedLocalCaretRectBidiTest,
1690        InRtlBlockLineEndRtlBaseRunWithTwoNestedRuns) {
1691   // Sample: D E F a b c|
1692   // Bidi:   1 1 1 2 2 2
1693   // Visual:|a b c F E D
1694   LoadAhem();
1695   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1696   const Position position = SetCaretTextToBody(
1697       "<div dir=rtl><bdo dir=rtl>DEF<bdo dir=ltr>abc|</bdo></bdo></div>");
1698   const PositionWithAffinity position_with_affinity(position,
1699                                                     TextAffinity::kDownstream);
1700   EXPECT_EQ(PhysicalRect(240, 0, 1, 10),
1701             LocalCaretRectOfPosition(position_with_affinity).rect);
1702 }
1703 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineEndRtlBaseRunWithThreeNestedRuns)1704 TEST_P(ParameterizedLocalCaretRectBidiTest,
1705        InRtlBlockLineEndRtlBaseRunWithThreeNestedRuns) {
1706   // Sample: G H I d e f A B C|
1707   // Bidi:   1 1 1 2 2 2 3 3 3
1708   // Visual:|d e f C B A I H G
1709   LoadAhem();
1710   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1711   const Position position = SetCaretTextToBody(
1712       "<div dir=rtl><bdo dir=rtl>GHI<bdo dir=ltr>def<bdo "
1713       "dir=rtl>ABC|</bdo></bdo></bdo></div>");
1714   const PositionWithAffinity position_with_affinity(position,
1715                                                     TextAffinity::kDownstream);
1716   EXPECT_EQ(PhysicalRect(210, 0, 1, 10),
1717             LocalCaretRectOfPosition(position_with_affinity).rect);
1718 }
1719 
TEST_P(ParameterizedLocalCaretRectBidiTest,InRtlBlockLineEndRtlBaseRunWithFourNestedRuns)1720 TEST_P(ParameterizedLocalCaretRectBidiTest,
1721        InRtlBlockLineEndRtlBaseRunWithFourNestedRuns) {
1722   // Sample: J K L g h i D E F a b c|
1723   // Bidi:   1 1 1 2 2 2 3 3 3 4 4 4
1724   // Visual: g h i|a b c F E D L K J
1725   LoadAhem();
1726   InsertStyleElement("div {font: 10px/10px Ahem; width: 300px}");
1727   const Position position = SetCaretTextToBody(
1728       "<div dir=rtl><bdo dir=rtl>JKL<bdo dir=ltr>ghi<bdo dir=rtl>DEF<bdo "
1729       "dir=ltr>abc|</bdo></bdo></bdo></bdo></div>");
1730   const PositionWithAffinity position_with_affinity(position,
1731                                                     TextAffinity::kDownstream);
1732   EXPECT_EQ(PhysicalRect(210, 0, 1, 10),
1733             LocalCaretRectOfPosition(position_with_affinity).rect);
1734 }
1735 
1736 }  // namespace blink
1737