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_units.h" | 7 #include "core/layout/ng/ng_units.h" |
8 #include "wtf/NonCopyingSort.h" | |
9 #include <climits> | |
8 | 10 |
9 namespace blink { | 11 namespace blink { |
10 | 12 |
11 // TODO: This should set the size of the NGPhysicalConstraintSpace. Or we could | 13 // TODO: This should set the size of the NGPhysicalConstraintSpace. Or we could |
12 // remove it requiring that a NGConstraintSpace is created from a | 14 // remove it requiring that a NGConstraintSpace is created from a |
13 // NGPhysicalConstraintSpace. | 15 // NGPhysicalConstraintSpace. |
14 NGConstraintSpace::NGConstraintSpace(NGWritingMode writing_mode, | 16 NGConstraintSpace::NGConstraintSpace(NGWritingMode writing_mode, |
15 NGLogicalSize container_size) | 17 NGLogicalSize container_size) |
16 : physical_space_(new NGPhysicalConstraintSpace( | 18 : physical_space_(new NGPhysicalConstraintSpace( |
17 container_size.ConvertToPhysical(writing_mode))), | 19 container_size.ConvertToPhysical(writing_mode))), |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 return static_cast<NGFragmentationType>( | 109 return static_cast<NGFragmentationType>( |
108 writing_mode_ == HorizontalTopBottom | 110 writing_mode_ == HorizontalTopBottom |
109 ? physical_space_->height_direction_fragmentation_type_ | 111 ? physical_space_->height_direction_fragmentation_type_ |
110 : physical_space_->width_direction_fragmentation_type_); | 112 : physical_space_->width_direction_fragmentation_type_); |
111 } | 113 } |
112 | 114 |
113 void NGConstraintSpace::Subtract(const NGFragment*) { | 115 void NGConstraintSpace::Subtract(const NGFragment*) { |
114 // TODO(layout-ng): Implement. | 116 // TODO(layout-ng): Implement. |
115 } | 117 } |
116 | 118 |
117 NGLayoutOpportunityIterator NGConstraintSpace::LayoutOpportunities( | 119 NGLayoutOpportunityIterator* NGConstraintSpace::LayoutOpportunities( |
118 unsigned clear, | 120 unsigned clear, |
119 bool for_inline_or_bfc) { | 121 bool for_inline_or_bfc) { |
120 NGLayoutOpportunityIterator iterator(this, clear, for_inline_or_bfc); | 122 NGLayoutOpportunityIterator* iterator = |
123 new NGLayoutOpportunityIterator(this, clear, for_inline_or_bfc); | |
121 return iterator; | 124 return iterator; |
122 } | 125 } |
123 | 126 |
124 void NGConstraintSpace::SetOverflowTriggersScrollbar(bool inline_triggers, | 127 void NGConstraintSpace::SetOverflowTriggersScrollbar(bool inline_triggers, |
125 bool block_triggers) { | 128 bool block_triggers) { |
126 if (writing_mode_ == HorizontalTopBottom) { | 129 if (writing_mode_ == HorizontalTopBottom) { |
127 physical_space_->width_direction_triggers_scrollbar_ = inline_triggers; | 130 physical_space_->width_direction_triggers_scrollbar_ = inline_triggers; |
128 physical_space_->height_direction_triggers_scrollbar_ = block_triggers; | 131 physical_space_->height_direction_triggers_scrollbar_ = block_triggers; |
129 } else { | 132 } else { |
130 physical_space_->width_direction_triggers_scrollbar_ = block_triggers; | 133 physical_space_->width_direction_triggers_scrollbar_ = block_triggers; |
(...skipping 24 matching lines...) Expand all Loading... | |
155 physical_space_->width_direction_triggers_scrollbar_ = type; | 158 physical_space_->width_direction_triggers_scrollbar_ = type; |
156 } | 159 } |
157 } | 160 } |
158 | 161 |
159 String NGConstraintSpace::toString() const { | 162 String NGConstraintSpace::toString() const { |
160 return String::format("Size: %s, %s", | 163 return String::format("Size: %s, %s", |
161 size_.inline_size.toString().ascii().data(), | 164 size_.inline_size.toString().ascii().data(), |
162 size_.block_size.toString().ascii().data()); | 165 size_.block_size.toString().ascii().data()); |
163 } | 166 } |
164 | 167 |
168 static bool ascendingTopCompare(const NGExclusion& a, const NGExclusion& b) { | |
169 return a.Top() > b.Top(); | |
170 } | |
171 | |
172 NGLayoutOpportunityIterator::NGLayoutOpportunityIterator( | |
173 NGConstraintSpace* space, | |
174 unsigned clear, | |
175 bool for_inline_or_bfc) | |
176 : constraint_space_(space), | |
177 clear_(clear), | |
178 for_inline_or_bfc_(for_inline_or_bfc), | |
179 current_exclusion_(0) { | |
180 for (auto item : constraint_space_->PhysicalSpace()->Exclusions()) | |
181 filtered_exclusions_.append(item); | |
ikilpatrick
2016/09/06 23:09:40
I'm assuming:
filtered_exclusions_(constaint_space
eae
2016/09/06 23:30:53
Correct
| |
182 | |
183 nonCopyingSort(filtered_exclusions_.begin(), filtered_exclusions_.end(), | |
184 ascendingTopCompare); | |
185 | |
186 // TODO: Set based on offset once that has been moved to NGConstraintSpace. | |
187 LayoutUnit left; | |
188 LayoutUnit top; | |
189 | |
190 unsigned i = filtered_exclusions_.size(); | |
191 while (i--) { | |
192 const NGExclusion& exclusion = filtered_exclusions_[i]; | |
193 | |
194 // Remove items above OR to the left of the start offset as they have no | |
195 // effect on layout opportunities within this view. | |
196 if (exclusion.Right() <= left || exclusion.Bottom() <= top) { | |
ikilpatrick
2016/09/06 23:09:40
I think we'll eventually want to do this in logica
eae
2016/09/06 23:30:53
Yeah, I think so too. At least for the inline case
| |
197 filtered_exclusions_.remove(i); | |
198 continue; | |
199 } | |
200 | |
201 // Remove items below AND to the right of the current exclusions as they're | |
202 // occluded and won't affect the layout opportunities. | |
203 for (unsigned j = filtered_exclusions_.size() - 1; j > i; j--) { | |
204 const NGExclusion& item = filtered_exclusions_[j]; | |
205 if (item.Top() > exclusion.Top() && item.Left() > exclusion.Left()) | |
206 filtered_exclusions_.remove(j); | |
207 } | |
208 } | |
209 } | |
210 | |
211 LayoutUnit NGLayoutOpportunityIterator::heightForOpportunity( | |
ikilpatrick
2016/09/06 23:09:40
I'd comment this with:
For the given 2d range (op
eae
2016/09/06 23:30:53
Good one, done!
| |
212 LayoutUnit left, | |
213 LayoutUnit top, | |
214 LayoutUnit right, | |
215 LayoutUnit bottom) { | |
216 LayoutUnit minBottom = bottom; | |
ikilpatrick
2016/09/06 23:09:40
lowestBottom?
eae
2016/09/06 23:30:53
Done.
| |
217 for (const NGExclusion& exclusion : filtered_exclusions_) { | |
218 if (exclusion.Left() < right && exclusion.Right() > left && | |
219 exclusion.Bottom() > top && exclusion.Top() <= minBottom) | |
220 minBottom = exclusion.Top(); | |
221 } | |
222 return std::max(minBottom - top, LayoutUnit()); | |
223 } | |
224 | |
225 static bool descendingWidthCompare(const NGConstraintSpace* a, | |
226 const NGConstraintSpace* b) { | |
227 return a->Size().inline_size > b->Size().inline_size; | |
228 } | |
229 | |
230 void NGLayoutOpportunityIterator::computeForExclusion(unsigned index) { | |
231 current_opportunities_.clear(); | |
232 | |
233 // TODO(eae): Set based on index. | |
234 LayoutUnit left; | |
235 LayoutUnit top; | |
236 | |
237 // TODO(eae): Writing modes. | |
238 LayoutUnit right = constraint_space_->Size().inline_size; | |
239 LayoutUnit bottom = constraint_space_->Size().block_size; | |
240 | |
241 // TODO(eae): Filter based on clear_ and for_inline_or_bfc_. Return early for | |
242 // now to make it clear neither are supported yet. | |
243 if (clear_ != NGClearNone && for_inline_or_bfc_) | |
ikilpatrick
2016/09/06 23:09:40
DCHECK? hmm... not sure.
eae
2016/09/06 23:30:53
This is all very temporary...
| |
244 return; | |
245 | |
246 LayoutUnit opportunityHeight = heightForOpportunity(left, top, right, bottom); | |
247 if (opportunityHeight && right > left) | |
ikilpatrick
2016/09/06 23:09:40
explain / rename variables for this magic.
| |
248 addLayoutOpportunity(left, top, right - left, opportunityHeight); | |
249 | |
250 for (const NGExclusion& exclusion : filtered_exclusions_) { | |
ikilpatrick
2016/09/06 23:09:40
add comment here.
eae
2016/09/06 23:30:53
Done.
| |
251 opportunityHeight = | |
252 heightForOpportunity(left, top, exclusion.Left(), bottom); | |
253 if (opportunityHeight && exclusion.Left() > left) | |
254 addLayoutOpportunity(left, top, exclusion.Left() - left, | |
255 opportunityHeight); | |
256 } | |
257 | |
258 nonCopyingSort(current_opportunities_.begin(), current_opportunities_.end(), | |
259 descendingWidthCompare); | |
260 } | |
261 | |
262 void NGLayoutOpportunityIterator::addLayoutOpportunity(LayoutUnit left, | |
263 LayoutUnit top, | |
264 LayoutUnit right, | |
265 LayoutUnit bottom) { | |
266 current_opportunities_.append( | |
267 new NGConstraintSpace(*constraint_space_, NGLogicalOffset(left, top), | |
268 NGLogicalSize(right - left, bottom - top))); | |
269 } | |
270 | |
165 NGConstraintSpace* NGLayoutOpportunityIterator::Next() { | 271 NGConstraintSpace* NGLayoutOpportunityIterator::Next() { |
ikilpatrick
2016/09/06 23:09:40
i'd place this right below the ctor, so people kno
eae
2016/09/06 23:30:52
Good idea.
| |
166 auto* exclusions = constraint_space_->PhysicalSpace()->Exclusions(); | 272 if (!current_opportunities_.size() && |
167 if (!exclusions->head()) | 273 current_exclusion_ < filtered_exclusions_.size()) { |
274 computeForExclusion(current_exclusion_); | |
275 current_exclusion_++; | |
276 } | |
277 | |
278 if (current_opportunities_.size()) { | |
279 NGConstraintSpace* opportunity = current_opportunities_.last(); | |
280 current_opportunities_.removeLast(); | |
281 return opportunity; | |
282 } | |
283 | |
284 if (!filtered_exclusions_.size() && current_exclusion_ == 0) { | |
285 current_exclusion_++; | |
168 return new NGConstraintSpace(constraint_space_->WritingMode(), | 286 return new NGConstraintSpace(constraint_space_->WritingMode(), |
169 constraint_space_->PhysicalSpace()); | 287 constraint_space_->PhysicalSpace()); |
288 } | |
289 | |
170 return nullptr; | 290 return nullptr; |
171 } | 291 } |
172 | 292 |
173 } // namespace blink | 293 } // namespace blink |
OLD | NEW |