Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1280)

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc

Issue 2298273002: Initial exclusion aware layout opportunities implementation (Closed)
Patch Set: Address reviewer comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 inline bool AscendingTopCompare(const NGExclusion& a,
169 const NGExclusion& b) {
170 return a.Top() > b.Top();
171 }
172
173 NGLayoutOpportunityIterator::NGLayoutOpportunityIterator(
174 NGConstraintSpace* space,
175 unsigned clear,
176 bool for_inline_or_bfc)
177 : constraint_space_(space),
178 clear_(clear),
179 for_inline_or_bfc_(for_inline_or_bfc),
180 current_exclusion_idx_(0) {
181 for (const auto& item : constraint_space_->PhysicalSpace()->Exclusions())
182 filtered_exclusions_.append(item);
183
184 nonCopyingSort(filtered_exclusions_.begin(), filtered_exclusions_.end(),
185 AscendingTopCompare);
186
187 // TODO(eae): Set based on offset.
188 LayoutUnit left;
189 LayoutUnit top;
190
191 unsigned i = filtered_exclusions_.size();
192 while (i--) {
193 const NGExclusion& exclusion = filtered_exclusions_[i];
194
195 // Remove items above OR to the left of the start offset as they have no
196 // effect on layout opportunities within this view.
197 if (exclusion.Right() <= left || exclusion.Bottom() <= top) {
198 filtered_exclusions_.remove(i);
199 continue;
200 }
201
202 // Remove items below AND to the right of the current exclusions as they're
203 // occluded and won't affect the layout opportunities.
204 for (unsigned j = filtered_exclusions_.size() - 1; j > i; j--) {
205 const NGExclusion& item = filtered_exclusions_[j];
206 if (item.Top() > exclusion.Top() && item.Left() > exclusion.Left())
207 filtered_exclusions_.remove(j);
208 }
209 }
210 }
211
165 NGConstraintSpace* NGLayoutOpportunityIterator::Next() { 212 NGConstraintSpace* NGLayoutOpportunityIterator::Next() {
166 auto* exclusions = constraint_space_->PhysicalSpace()->Exclusions(); 213 if (current_opportunities_.isEmpty() &&
167 if (!exclusions->head()) 214 current_exclusion_idx_ < filtered_exclusions_.size()) {
215 computeForExclusion(current_exclusion_idx_);
216 current_exclusion_idx_++;
217 }
218
219 if (!current_opportunities_.isEmpty()) {
220 NGConstraintSpace* opportunity = current_opportunities_.last();
221 current_opportunities_.removeLast();
222 return opportunity;
223 }
224
225 if (filtered_exclusions_.isEmpty() && current_exclusion_idx_ == 0) {
226 current_exclusion_idx_++;
168 return new NGConstraintSpace(constraint_space_->WritingMode(), 227 return new NGConstraintSpace(constraint_space_->WritingMode(),
169 constraint_space_->PhysicalSpace()); 228 constraint_space_->PhysicalSpace());
229 }
230
170 return nullptr; 231 return nullptr;
171 } 232 }
172 233
234 static inline bool DescendingWidthCompare(const NGConstraintSpace* a,
235 const NGConstraintSpace* b) {
236 return a->Size().inline_size > b->Size().inline_size;
237 }
238
239 void NGLayoutOpportunityIterator::computeForExclusion(unsigned index) {
240 current_opportunities_.clear();
241
242 // TODO(eae): Set based on index.
243 LayoutUnit left;
244 LayoutUnit top;
245
246 // TODO(eae): Writing modes.
247 LayoutUnit right = constraint_space_->Size().inline_size;
248 LayoutUnit bottom = constraint_space_->Size().block_size;
249
250 // TODO(eae): Filter based on clear_ and for_inline_or_bfc_. Return early for
251 // now to make it clear neither are supported yet.
252 if (clear_ != NGClearNone || !for_inline_or_bfc_)
253 return;
254
255 // Compute opportunity for the full width from the start position to the right
256 // edge of the NGConstraintSpace.
257 LayoutUnit opportunityHeight = heightForOpportunity(left, top, right, bottom);
258 if (opportunityHeight && right > left)
259 addLayoutOpportunity(left, top, right - left, opportunityHeight);
260
261 // Compute the maximum available height between the current position and the
262 // left edge of each exclusion. The distance between the current horizontal
263 // position and the left edge of the exclusion determines the width of the
264 // opportunity.
265 for (const NGExclusion& exclusion : filtered_exclusions_) {
266 opportunityHeight =
267 heightForOpportunity(left, top, exclusion.Left(), bottom);
268 if (opportunityHeight && exclusion.Left() > left)
269 addLayoutOpportunity(left, top, exclusion.Left() - left,
270 opportunityHeight);
271 }
272
273 nonCopyingSort(current_opportunities_.begin(), current_opportunities_.end(),
274 DescendingWidthCompare);
275 }
276
277 // For the given 2D range (opportunity), this will return a height which makes
278 // it bounded by the highest exclusion in the filtered exclusion list within the
279 // range. Returns 0-height for an invalid opportunity (which has zero area).
280 LayoutUnit NGLayoutOpportunityIterator::heightForOpportunity(
281 LayoutUnit left,
282 LayoutUnit top,
283 LayoutUnit right,
284 LayoutUnit bottom) {
285 LayoutUnit lowestBottom = bottom;
286 for (const NGExclusion& exclusion : filtered_exclusions_) {
287 if (exclusion.Left() < right && exclusion.Right() > left &&
288 exclusion.Bottom() > top && exclusion.Top() <= lowestBottom)
289 lowestBottom = exclusion.Top();
290 }
291 return std::max(lowestBottom - top, LayoutUnit());
292 }
293
294 void NGLayoutOpportunityIterator::addLayoutOpportunity(LayoutUnit left,
295 LayoutUnit top,
296 LayoutUnit right,
297 LayoutUnit bottom) {
298 current_opportunities_.append(
299 new NGConstraintSpace(*constraint_space_, NGLogicalOffset(left, top),
300 NGLogicalSize(right - left, bottom - top)));
301 }
302
173 } // namespace blink 303 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698