OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/layout/ng/ng_constraint_space.h" | 5 #include "core/layout/ng/ng_constraint_space.h" |
6 | 6 |
7 #include "core/layout/ng/ng_constraint_space.h" | 7 #include "core/layout/ng/ng_constraint_space.h" |
8 #include "core/layout/ng/ng_constraint_space_builder.h" | 8 #include "core/layout/ng/ng_constraint_space_builder.h" |
9 #include "core/layout/ng/ng_layout_opportunity_iterator.h" | 9 #include "core/layout/ng/ng_layout_opportunity_iterator.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
11 | 11 |
12 namespace blink { | 12 namespace blink { |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 RefPtr<NGConstraintSpace> ConstructConstraintSpace(NGWritingMode writing_mode, | 16 RefPtr<NGConstraintSpace> ConstructConstraintSpace( |
17 TextDirection direction, | 17 NGWritingMode writing_mode, |
18 NGLogicalSize size) { | 18 TextDirection direction, |
| 19 NGLogicalSize size, |
| 20 const NGLogicalOffset& bfc_offset = {}) { |
19 return NGConstraintSpaceBuilder(writing_mode) | 21 return NGConstraintSpaceBuilder(writing_mode) |
20 .SetTextDirection(direction) | 22 .SetTextDirection(direction) |
21 .SetAvailableSize(size) | 23 .SetAvailableSize(size) |
22 .SetPercentageResolutionSize(size) | 24 .SetPercentageResolutionSize(size) |
23 .SetIsFixedSizeInline(true) | 25 .SetIsFixedSizeInline(true) |
24 .SetIsInlineDirectionTriggersScrollbar(true) | 26 .SetIsInlineDirectionTriggersScrollbar(true) |
25 .SetFragmentationType(NGFragmentationType::kFragmentColumn) | 27 .SetFragmentationType(NGFragmentationType::kFragmentColumn) |
| 28 .SetBfcOffset(bfc_offset) |
26 .ToConstraintSpace(writing_mode); | 29 .ToConstraintSpace(writing_mode); |
27 } | 30 } |
28 | 31 |
29 static String OpportunityToString(const NGLayoutOpportunity& opportunity) { | |
30 return opportunity.IsEmpty() ? String("(empty)") : opportunity.ToString(); | |
31 } | |
32 | |
33 TEST(NGConstraintSpaceTest, LayoutOpportunitiesNoExclusions) { | 32 TEST(NGConstraintSpaceTest, LayoutOpportunitiesNoExclusions) { |
34 NGLogicalSize size; | 33 NGLogicalSize size; |
35 size.inline_size = LayoutUnit(600); | 34 size.inline_size = LayoutUnit(600); |
36 size.block_size = LayoutUnit(400); | 35 size.block_size = LayoutUnit(400); |
37 RefPtr<NGConstraintSpace> space = | 36 RefPtr<NGConstraintSpace> space = |
38 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); | 37 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); |
39 | 38 |
40 NGLayoutOpportunityIterator iterator(space.get()); | 39 NGLayoutOpportunityIterator iterator(space.get()); |
41 EXPECT_EQ("0,0 600x400", OpportunityToString(iterator.Next())); | 40 // 600x400 at (0,0) |
42 EXPECT_EQ("(empty)", OpportunityToString(iterator.Next())); | 41 NGLayoutOpportunity opp1 = {{}, {LayoutUnit(600), LayoutUnit(400)}}; |
| 42 EXPECT_EQ(opp1, iterator.Next()); |
| 43 |
| 44 EXPECT_EQ(NGLayoutOpportunity(), iterator.Next()); |
43 } | 45 } |
44 | 46 |
45 TEST(NGConstraintSpaceTest, LayoutOpportunitiesTopRightExclusion) { | 47 TEST(NGConstraintSpaceTest, LayoutOpportunitiesTopRightExclusion) { |
46 NGLogicalSize size; | 48 NGLogicalSize size; |
47 size.inline_size = LayoutUnit(600); | 49 size.inline_size = LayoutUnit(600); |
48 size.block_size = LayoutUnit(400); | 50 size.block_size = LayoutUnit(400); |
49 // Create a space with a 100x100 exclusion in the top right corner. | 51 // Create a space with a 100x100 exclusion in the top right corner. |
50 RefPtr<NGConstraintSpace> space = | 52 RefPtr<NGConstraintSpace> space = |
51 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); | 53 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); |
52 NGExclusion exclusion; | 54 NGExclusion exclusion; |
53 exclusion.rect.size = {/* inline_size */ LayoutUnit(100), | 55 exclusion.rect.size = {LayoutUnit(100), LayoutUnit(100)}; |
54 /* block_size */ LayoutUnit(100)}; | 56 exclusion.rect.offset = {LayoutUnit(500), LayoutUnit()}; |
55 exclusion.rect.offset = {/* inline_offset */ LayoutUnit(500), | |
56 /* block_offset */ LayoutUnit(0)}; | |
57 space->AddExclusion(exclusion); | 57 space->AddExclusion(exclusion); |
58 | 58 |
59 NGLayoutOpportunityIterator iterator(space.get()); | 59 NGLayoutOpportunityIterator iterator(space.get()); |
60 // First opportunity should be to the left of the exclusion. | 60 |
61 EXPECT_EQ("0,0 500x400", OpportunityToString(iterator.Next())); | 61 // First opportunity should be to the left of the exclusion: 500x400 at (0,0) |
62 // Second opportunity should be below the exclusion. | 62 NGLayoutOpportunity opp1 = {{}, {LayoutUnit(500), LayoutUnit(400)}}; |
63 EXPECT_EQ("0,100 600x300", OpportunityToString(iterator.Next())); | 63 EXPECT_EQ(opp1, iterator.Next()); |
64 // There should be no third opportunity. | 64 |
65 EXPECT_EQ("(empty)", OpportunityToString(iterator.Next())); | 65 // Second opportunity should be below the exclusion: 600x300 at (0,100) |
| 66 NGLayoutOpportunity opp2 = {{LayoutUnit(), LayoutUnit(100)}, |
| 67 {LayoutUnit(600), LayoutUnit(300)}}; |
| 68 EXPECT_EQ(opp2, iterator.Next()); |
| 69 |
| 70 EXPECT_EQ(NGLayoutOpportunity(), iterator.Next()); |
66 } | 71 } |
67 | 72 |
68 TEST(NGConstraintSpaceTest, LayoutOpportunitiesTopLeftExclusion) { | 73 TEST(NGConstraintSpaceTest, LayoutOpportunitiesTopLeftExclusion) { |
69 NGLogicalSize size; | 74 NGLogicalSize size; |
70 size.inline_size = LayoutUnit(600); | 75 size.inline_size = LayoutUnit(600); |
71 size.block_size = LayoutUnit(400); | 76 size.block_size = LayoutUnit(400); |
72 // Create a space with a 100x100 exclusion in the top left corner. | 77 // Create a space with a 100x100 exclusion in the top left corner. |
73 RefPtr<NGConstraintSpace> space = | 78 RefPtr<NGConstraintSpace> space = |
74 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); | 79 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); |
75 NGExclusion exclusion; | 80 NGExclusion exclusion; |
76 exclusion.rect.size = {/* inline_size */ LayoutUnit(100), | 81 exclusion.rect.size = {LayoutUnit(100), LayoutUnit(100)}; |
77 /* block_size */ LayoutUnit(100)}; | |
78 exclusion.rect.offset = {/* inline_offset */ LayoutUnit(0), | |
79 /* block_offset */ LayoutUnit(0)}; | |
80 space->AddExclusion(exclusion); | 82 space->AddExclusion(exclusion); |
81 | 83 |
82 NGLayoutOpportunityIterator iterator(space.get()); | 84 NGLayoutOpportunityIterator iterator(space.get()); |
83 // First opportunity should be to the right of the exclusion. | 85 // First opportunity should be to the right of the exclusion: |
84 EXPECT_EQ("100,0 500x400", OpportunityToString(iterator.Next())); | 86 // 500x400 at (100, 0) |
85 // Second opportunity should be below the exclusion. | 87 NGLayoutOpportunity opp1 = {{LayoutUnit(100), LayoutUnit()}, |
86 EXPECT_EQ("0,100 600x300", OpportunityToString(iterator.Next())); | 88 {LayoutUnit(500), LayoutUnit(400)}}; |
87 // There should be no third opportunity. | 89 EXPECT_EQ(opp1, iterator.Next()); |
88 EXPECT_EQ("(empty)", OpportunityToString(iterator.Next())); | 90 |
| 91 // Second opportunity should be below the exclusion: 600x300 at (0,100) |
| 92 NGLayoutOpportunity opp2 = {{LayoutUnit(), LayoutUnit(100)}, |
| 93 {LayoutUnit(600), LayoutUnit(300)}}; |
| 94 EXPECT_EQ(opp2, iterator.Next()); |
| 95 |
| 96 EXPECT_EQ(NGLayoutOpportunity(), iterator.Next()); |
89 } | 97 } |
90 | 98 |
91 // Verifies that Layout Opportunity iterator produces 7 layout opportunities | 99 // Verifies that Layout Opportunity iterator produces 7 layout opportunities |
92 // from 4 start points created by 2 CSS exclusions positioned in the middle of | 100 // from 4 start points created by 2 CSS exclusions positioned in the middle of |
93 // the main constraint space. | 101 // the main constraint space. |
94 // | 102 // |
95 // Test case visual representation: | 103 // Test case visual representation: |
96 // | 104 // |
97 // 100 200 300 400 500 | 105 // 100 200 300 400 500 |
98 // (1)--|----|-(2)-|----|----|-(3)-+ | 106 // (1)--|----|-(2)-|----|----|-(3)-+ |
(...skipping 13 matching lines...) Expand all Loading... |
112 // - 3rd Start Point: 550,0 50x400 | 120 // - 3rd Start Point: 550,0 50x400 |
113 // - 4th Start Point: 0,300 600x50; 0,300 500x100 | 121 // - 4th Start Point: 0,300 600x50; 0,300 500x100 |
114 TEST(NGConstraintSpaceTest, LayoutOpportunitiesTwoInMiddle) { | 122 TEST(NGConstraintSpaceTest, LayoutOpportunitiesTwoInMiddle) { |
115 NGLogicalSize size; | 123 NGLogicalSize size; |
116 size.inline_size = LayoutUnit(600); | 124 size.inline_size = LayoutUnit(600); |
117 size.block_size = LayoutUnit(400); | 125 size.block_size = LayoutUnit(400); |
118 RefPtr<NGConstraintSpace> space = | 126 RefPtr<NGConstraintSpace> space = |
119 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); | 127 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); |
120 // Add exclusions | 128 // Add exclusions |
121 NGExclusion exclusion1; | 129 NGExclusion exclusion1; |
122 exclusion1.rect.size = {/* inline_size */ LayoutUnit(100), | 130 exclusion1.rect.size = {LayoutUnit(100), LayoutUnit(100)}; |
123 /* block_size */ LayoutUnit(100)}; | 131 exclusion1.rect.offset = {LayoutUnit(150), LayoutUnit(200)}; |
124 exclusion1.rect.offset = {/* inline_offset */ LayoutUnit(150), | |
125 /* block_offset */ LayoutUnit(200)}; | |
126 space->AddExclusion(exclusion1); | 132 space->AddExclusion(exclusion1); |
127 NGExclusion exclusion2; | 133 NGExclusion exclusion2; |
128 exclusion2.rect.size = {/* inline_size */ LayoutUnit(50), | 134 exclusion2.rect.size = {LayoutUnit(50), LayoutUnit(50)}; |
129 /* block_size */ LayoutUnit(50)}; | 135 exclusion2.rect.offset = {LayoutUnit(500), LayoutUnit(350)}; |
130 exclusion2.rect.offset = {/* inline_offset */ LayoutUnit(500), | |
131 /* block_offset */ LayoutUnit(350)}; | |
132 space->AddExclusion(exclusion2); | 136 space->AddExclusion(exclusion2); |
133 | 137 |
134 NGLayoutOpportunityIterator iterator(space.get()); | 138 NGLayoutOpportunityIterator iterator(space.get()); |
135 // 1st Start point | 139 NGLogicalOffset start_point1; |
136 EXPECT_EQ("0,0 600x200", OpportunityToString(iterator.Next())); | 140 // 600x200 at (0,0) |
137 EXPECT_EQ("0,0 150x400", OpportunityToString(iterator.Next())); | 141 NGLayoutOpportunity opp1 = {start_point1, {LayoutUnit(600), LayoutUnit(200)}}; |
138 // 2nd Start point | 142 EXPECT_EQ(opp1, (iterator.Next())); |
139 EXPECT_EQ("250,0 350x350", OpportunityToString(iterator.Next())); | 143 // 150x400 at (0,0) |
140 EXPECT_EQ("250,0 250x400", OpportunityToString(iterator.Next())); | 144 NGLayoutOpportunity opp2 = {start_point1, {LayoutUnit(150), LayoutUnit(400)}}; |
141 // 3rd Start point | 145 EXPECT_EQ(opp2, (iterator.Next())); |
142 EXPECT_EQ("550,0 50x400", OpportunityToString(iterator.Next())); | 146 |
143 // 4th Start point | 147 NGLogicalOffset start_point2 = {LayoutUnit(250), LayoutUnit()}; |
144 EXPECT_EQ("0,300 600x50", OpportunityToString(iterator.Next())); | 148 // 350x350 at (250,0) |
145 EXPECT_EQ("0,300 500x100", OpportunityToString(iterator.Next())); | 149 NGLayoutOpportunity opp3 = {start_point2, {LayoutUnit(350), LayoutUnit(350)}}; |
146 // Iterator is exhausted. | 150 EXPECT_EQ(opp3, (iterator.Next())); |
147 EXPECT_EQ("(empty)", OpportunityToString(iterator.Next())); | 151 // 250x400 at (250,0) |
| 152 NGLayoutOpportunity opp4 = {start_point2, {LayoutUnit(250), LayoutUnit(400)}}; |
| 153 EXPECT_EQ(opp4, (iterator.Next())); |
| 154 |
| 155 NGLogicalOffset start_point3 = {LayoutUnit(550), LayoutUnit()}; |
| 156 // 50x400 at (550,0) |
| 157 NGLayoutOpportunity opp5 = {start_point3, {LayoutUnit(50), LayoutUnit(400)}}; |
| 158 EXPECT_EQ(opp5, (iterator.Next())); |
| 159 |
| 160 NGLogicalOffset start_point4 = {LayoutUnit(), LayoutUnit(300)}; |
| 161 // 600x50 at (0,300) |
| 162 NGLayoutOpportunity opp6 = {start_point4, {LayoutUnit(600), LayoutUnit(50)}}; |
| 163 EXPECT_EQ(opp6, (iterator.Next())); |
| 164 // 500x100 at (0,300) |
| 165 NGLayoutOpportunity opp7 = {start_point4, {LayoutUnit(500), LayoutUnit(100)}}; |
| 166 EXPECT_EQ(opp7, (iterator.Next())); |
| 167 |
| 168 EXPECT_EQ(NGLayoutOpportunity(), iterator.Next()); |
148 } | 169 } |
149 | 170 |
150 // This test is the same as LayoutOpportunitiesTwoInMiddle with the only | 171 // This test is the same as LayoutOpportunitiesTwoInMiddle with the only |
151 // difference that NGLayoutOpportunityIterator takes 2 additional arguments: | 172 // difference that NGLayoutOpportunityIterator takes 2 additional arguments: |
152 // - origin_point that changes the iterator to return Layout Opportunities that | 173 // - origin_point that changes the iterator to return Layout Opportunities that |
153 // lay after the origin point. | 174 // lay after the origin point. |
154 // - leader_point that together with origin_point creates a temporary exclusion | 175 // - leader_point that together with origin_point creates a temporary exclusion |
155 // | 176 // |
156 // Expected: | 177 // Expected: |
157 // Layout opportunity iterator generates the next opportunities: | 178 // Layout opportunity iterator generates the next opportunities: |
158 // - 1st Start Point (0, 200): 350x150, 250x400 | 179 // - 1st Start Point (0, 200): 350x150, 250x400 |
159 // - 3rd Start Point (550, 200): 50x400 | 180 // - 3rd Start Point (550, 200): 50x400 |
160 // - 4th Start Point (0, 300): 600x50, 500x300 | 181 // - 4th Start Point (0, 300): 600x50, 500x300 |
161 // - 5th Start Point (0, 400): 600x200 | 182 // - 5th Start Point (0, 400): 600x200 |
162 // All other opportunities that are located before the origin point should be | 183 // All other opportunities that are located before the origin point should be |
163 // filtered out. | 184 // filtered out. |
164 TEST(NGConstraintSpaceTest, LayoutOpportunitiesTwoInMiddleWithOriginAndLeader) { | 185 TEST(NGConstraintSpaceTest, LayoutOpportunitiesTwoInMiddleWithOriginAndLeader) { |
165 NGLogicalSize size; | 186 NGLogicalSize size; |
166 size.inline_size = LayoutUnit(600); | 187 size.inline_size = LayoutUnit(600); |
167 size.block_size = LayoutUnit(400); | 188 size.block_size = LayoutUnit(400); |
168 RefPtr<NGConstraintSpace> space = | 189 RefPtr<NGConstraintSpace> space = |
169 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); | 190 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); |
170 // Add exclusions | 191 // Add exclusions |
171 NGExclusion exclusion1; | 192 NGExclusion exclusion1; |
172 exclusion1.rect.size = {/* inline_size */ LayoutUnit(100), | 193 exclusion1.rect.size = {LayoutUnit(100), LayoutUnit(100)}; |
173 /* block_size */ LayoutUnit(100)}; | 194 exclusion1.rect.offset = {LayoutUnit(150), LayoutUnit(200)}; |
174 exclusion1.rect.offset = {/* inline_offset */ LayoutUnit(150), | |
175 /* block_offset */ LayoutUnit(200)}; | |
176 space->AddExclusion(exclusion1); | 195 space->AddExclusion(exclusion1); |
177 NGExclusion exclusion2; | 196 NGExclusion exclusion2; |
178 exclusion2.rect.size = {/* inline_size */ LayoutUnit(50), | 197 exclusion2.rect.size = {LayoutUnit(50), LayoutUnit(50)}; |
179 /* block_size */ LayoutUnit(50)}; | 198 exclusion2.rect.offset = {LayoutUnit(500), LayoutUnit(350)}; |
180 exclusion2.rect.offset = {/* inline_offset */ LayoutUnit(500), | |
181 /* block_offset */ LayoutUnit(350)}; | |
182 space->AddExclusion(exclusion2); | 199 space->AddExclusion(exclusion2); |
183 | 200 |
184 const NGLogicalOffset origin_point = {LayoutUnit(0), LayoutUnit(200)}; | 201 const NGLogicalOffset origin_point = {LayoutUnit(), LayoutUnit(200)}; |
185 const NGLogicalOffset leader_point = {LayoutUnit(250), LayoutUnit(300)}; | 202 const NGLogicalOffset leader_point = {LayoutUnit(250), LayoutUnit(300)}; |
186 NGLayoutOpportunityIterator iterator(space.get(), origin_point, leader_point); | 203 NGLayoutOpportunityIterator iterator(space.get(), origin_point, leader_point); |
187 // 1st Start Point | 204 |
188 EXPECT_EQ("250,200 350x150", OpportunityToString(iterator.Next())); | 205 NGLogicalOffset start_point1 = {LayoutUnit(250), LayoutUnit(200)}; |
189 EXPECT_EQ("250,200 250x400", OpportunityToString(iterator.Next())); | 206 // 350x150 at (250,200) |
190 // 2nd Start Point | 207 NGLayoutOpportunity opp1 = {start_point1, {LayoutUnit(350), LayoutUnit(150)}}; |
191 EXPECT_EQ("550,200 50x400", OpportunityToString(iterator.Next())); | 208 EXPECT_EQ(opp1, iterator.Next()); |
192 // 3rd Start Point | 209 // 250x400 at (250,200) |
193 EXPECT_EQ("0,300 600x50", OpportunityToString(iterator.Next())); | 210 NGLayoutOpportunity opp2 = {start_point1, {LayoutUnit(250), LayoutUnit(400)}}; |
194 EXPECT_EQ("0,300 500x300", OpportunityToString(iterator.Next())); | 211 EXPECT_EQ(opp2, iterator.Next()); |
| 212 |
| 213 NGLogicalOffset start_point2 = {LayoutUnit(550), LayoutUnit(200)}; |
| 214 // 50x400 at (550,200) |
| 215 NGLayoutOpportunity opp3 = {start_point2, {LayoutUnit(50), LayoutUnit(400)}}; |
| 216 EXPECT_EQ(opp3, iterator.Next()); |
| 217 |
| 218 NGLogicalOffset start_point3 = {LayoutUnit(), LayoutUnit(300)}; |
| 219 // 600x50 at (0,300) |
| 220 NGLayoutOpportunity opp4 = {start_point3, {LayoutUnit(600), LayoutUnit(50)}}; |
| 221 EXPECT_EQ(opp4, iterator.Next()); |
| 222 // 500x300 at (0,300) |
| 223 NGLayoutOpportunity opp5 = {start_point3, {LayoutUnit(500), LayoutUnit(300)}}; |
| 224 EXPECT_EQ(opp5, iterator.Next()); |
| 225 |
195 // 4th Start Point | 226 // 4th Start Point |
196 EXPECT_EQ("0,400 600x200", OpportunityToString(iterator.Next())); | 227 NGLogicalOffset start_point4 = {LayoutUnit(), LayoutUnit(400)}; |
| 228 // 600x200 at (0,400) |
| 229 NGLayoutOpportunity opp6 = {start_point4, {LayoutUnit(600), LayoutUnit(200)}}; |
| 230 EXPECT_EQ(opp6, iterator.Next()); |
| 231 |
197 // TODO(glebl): The opportunity below should not be generated. | 232 // TODO(glebl): The opportunity below should not be generated. |
198 EXPECT_EQ("250,400 350x200", OpportunityToString(iterator.Next())); | 233 EXPECT_EQ("350x200 at (250,400)", iterator.Next().ToString()); |
199 // Iterator is exhausted. | 234 |
200 EXPECT_EQ("(empty)", OpportunityToString(iterator.Next())); | 235 EXPECT_EQ(NGLayoutOpportunity(), iterator.Next()); |
201 } | 236 } |
| 237 |
202 // Verifies that Layout Opportunity iterator ignores the exclusion that is not | 238 // Verifies that Layout Opportunity iterator ignores the exclusion that is not |
203 // within constraint space. | 239 // within constraint space. |
204 // | 240 // |
205 // Test case visual representation: | 241 // Test case visual representation: |
206 // | 242 // |
207 // 100 200 300 400 500 | 243 // 100 200 300 400 500 |
208 // +----|----|----|----|----|----+ | 244 // +----|----|----|----|----|----+ |
209 // 50 | | | 245 // 50 | | |
210 // 100 | | | 246 // 100 | | |
211 // +-----------------------------+ | 247 // +-----------------------------+ |
212 // *** <- Exclusion | 248 // *** <- Exclusion |
213 // | 249 // |
214 // Expected: | 250 // Expected: |
215 // Layout opportunity iterator generates only one opportunity that equals to | 251 // Layout opportunity iterator generates only one opportunity that equals to |
216 // available constraint space, i.e. 0,0 600x200 | 252 // available constraint space, i.e. 0,0 600x200 |
217 TEST(NGConstraintSpaceTest, LayoutOpportunitiesWithOutOfBoundsExclusions) { | 253 TEST(NGConstraintSpaceTest, LayoutOpportunitiesWithOutOfBoundsExclusions) { |
218 NGLogicalSize size; | 254 NGLogicalSize size = {LayoutUnit(600), LayoutUnit(100)}; |
219 size.inline_size = LayoutUnit(600); | |
220 size.block_size = LayoutUnit(100); | |
221 RefPtr<NGConstraintSpace> space = | 255 RefPtr<NGConstraintSpace> space = |
222 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); | 256 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, size); |
223 NGExclusion exclusion; | 257 NGExclusion exclusion; |
224 exclusion.rect.size = {/* inline_size */ LayoutUnit(100), | 258 exclusion.rect.size = {LayoutUnit(100), LayoutUnit(100)}; |
225 /* block_size */ LayoutUnit(100)}; | 259 exclusion.rect.offset = {LayoutUnit(), LayoutUnit(150)}; |
226 exclusion.rect.offset = {/* inline_offset */ LayoutUnit(0), | |
227 /* block_offset */ LayoutUnit(150)}; | |
228 space->AddExclusion(exclusion); | 260 space->AddExclusion(exclusion); |
229 | 261 |
230 NGLayoutOpportunityIterator iterator(space.get()); | 262 NGLayoutOpportunityIterator iterator(space.get()); |
231 EXPECT_EQ("0,0 600x100", OpportunityToString(iterator.Next())); | 263 // 600x100 at (0,0) |
232 EXPECT_EQ("(empty)", OpportunityToString(iterator.Next())); | 264 NGLayoutOpportunity opp = {{}, size}; |
| 265 EXPECT_EQ(opp, iterator.Next()); |
| 266 |
| 267 EXPECT_EQ(NGLayoutOpportunity(), iterator.Next()); |
| 268 } |
| 269 |
| 270 // Verifies that we combine 2 adjoining left exclusions into one left exclusion. |
| 271 TEST(NGConstraintSpaceTest, TwoLeftExclusionsShadowEachOther) { |
| 272 NGLogicalOffset bfc_offset = {LayoutUnit(8), LayoutUnit(8)}; |
| 273 RefPtr<NGConstraintSpace> space = |
| 274 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, |
| 275 {LayoutUnit(200), LayoutUnit(200)}, bfc_offset); |
| 276 |
| 277 NGExclusion small_left; |
| 278 small_left.rect.size = {LayoutUnit(10), LayoutUnit(10)}; |
| 279 small_left.rect.offset = bfc_offset; |
| 280 small_left.type = NGExclusion::kFloatLeft; |
| 281 space->AddExclusion(small_left); |
| 282 |
| 283 NGExclusion big_left; |
| 284 big_left.rect.size = {LayoutUnit(20), LayoutUnit(20)}; |
| 285 big_left.rect.offset = bfc_offset; |
| 286 big_left.rect.offset.inline_offset += small_left.rect.InlineSize(); |
| 287 big_left.type = NGExclusion::kFloatLeft; |
| 288 space->AddExclusion(big_left); |
| 289 |
| 290 NGLayoutOpportunityIterator iterator(space.get(), bfc_offset); |
| 291 |
| 292 NGLogicalOffset start_point1 = bfc_offset; |
| 293 start_point1.inline_offset += |
| 294 small_left.rect.InlineSize() + big_left.rect.InlineSize(); |
| 295 // 170x200 at (38, 8) |
| 296 NGLayoutOpportunity opportunity1 = {start_point1, |
| 297 {LayoutUnit(170), LayoutUnit(200)}}; |
| 298 EXPECT_EQ(opportunity1, iterator.Next()); |
| 299 |
| 300 NGLogicalOffset start_point2 = bfc_offset; |
| 301 start_point2.block_offset += big_left.rect.BlockSize(); |
| 302 // 200x180 at (8, 28) |
| 303 NGLayoutOpportunity opportunity2 = {start_point2, |
| 304 {LayoutUnit(200), LayoutUnit(180)}}; |
| 305 EXPECT_EQ(opportunity2, iterator.Next()); |
| 306 |
| 307 EXPECT_EQ(NGLayoutOpportunity(), iterator.Next()); |
| 308 } |
| 309 |
| 310 // Verifies that we combine 2 adjoining right exclusions into one right |
| 311 // exclusion. |
| 312 TEST(NGConstraintSpaceTest, TwoRightExclusionsShadowEachOther) { |
| 313 NGLogicalOffset bfc_offset = {LayoutUnit(8), LayoutUnit(8)}; |
| 314 RefPtr<NGConstraintSpace> space = |
| 315 ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, |
| 316 {LayoutUnit(200), LayoutUnit(200)}, bfc_offset); |
| 317 |
| 318 NGExclusion small_right; |
| 319 small_right.rect.size = {LayoutUnit(10), LayoutUnit(10)}; |
| 320 small_right.rect.offset = bfc_offset; |
| 321 small_right.rect.offset.inline_offset += |
| 322 space->AvailableSize().inline_size - small_right.rect.InlineSize(); |
| 323 small_right.type = NGExclusion::kFloatRight; |
| 324 space->AddExclusion(small_right); |
| 325 |
| 326 NGExclusion big_right; |
| 327 big_right.rect.size = {LayoutUnit(20), LayoutUnit(20)}; |
| 328 big_right.rect.offset = bfc_offset; |
| 329 big_right.rect.offset.inline_offset += space->AvailableSize().inline_size - |
| 330 small_right.rect.InlineSize() - |
| 331 big_right.rect.InlineSize(); |
| 332 big_right.type = NGExclusion::kFloatRight; |
| 333 space->AddExclusion(big_right); |
| 334 |
| 335 NGLayoutOpportunityIterator iterator(space.get(), bfc_offset); |
| 336 |
| 337 NGLogicalOffset start_point1 = bfc_offset; |
| 338 // 170x200 at (8, 8) |
| 339 NGLayoutOpportunity opportunity1 = {start_point1, |
| 340 {LayoutUnit(170), LayoutUnit(200)}}; |
| 341 EXPECT_EQ(opportunity1, iterator.Next()); |
| 342 |
| 343 NGLogicalOffset start_point2 = bfc_offset; |
| 344 start_point2.block_offset += big_right.rect.BlockSize(); |
| 345 // 200x180 at (8, 28) |
| 346 NGLayoutOpportunity opportunity2 = {start_point2, |
| 347 {LayoutUnit(200), LayoutUnit(180)}}; |
| 348 EXPECT_EQ(opportunity2, iterator.Next()); |
| 349 |
| 350 EXPECT_EQ(NGLayoutOpportunity(), iterator.Next()); |
233 } | 351 } |
234 | 352 |
235 } // namespace | 353 } // namespace |
236 } // namespace blink | 354 } // namespace blink |
OLD | NEW |