Chromium Code Reviews| 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 |