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

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

Issue 2810833003: Move container_builder to NGLayoutAlgorithm base class. (Closed)
Patch Set: git rebase-update Created 3 years, 8 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_block_layout_algorithm.h" 5 #include "core/layout/ng/ng_block_layout_algorithm.h"
6 6
7 #include "core/layout/ng/inline/ng_inline_node.h" 7 #include "core/layout/ng/inline/ng_inline_node.h"
8 #include "core/layout/ng/ng_absolute_utils.h" 8 #include "core/layout/ng/ng_absolute_utils.h"
9 #include "core/layout/ng/ng_block_child_iterator.h" 9 #include "core/layout/ng/ng_block_child_iterator.h"
10 #include "core/layout/ng/ng_box_fragment.h" 10 #include "core/layout/ng/ng_box_fragment.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 NGLogicalOffset mutable_offset(offset); 81 NGLogicalOffset mutable_offset(offset);
82 AdjustToClearance(space.ClearanceOffset(), &mutable_offset); 82 AdjustToClearance(space.ClearanceOffset(), &mutable_offset);
83 builder->SetBfcOffset(mutable_offset); 83 builder->SetBfcOffset(mutable_offset);
84 } 84 }
85 } 85 }
86 86
87 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(NGBlockNode* node, 87 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(NGBlockNode* node,
88 NGConstraintSpace* space, 88 NGConstraintSpace* space,
89 NGBlockBreakToken* break_token) 89 NGBlockBreakToken* break_token)
90 : NGLayoutAlgorithm(node, space, break_token), 90 : NGLayoutAlgorithm(node, space, break_token),
91 builder_(NGPhysicalFragment::kFragmentBox, node),
92 space_builder_(constraint_space_) {} 91 space_builder_(constraint_space_) {}
93 92
94 Optional<MinMaxContentSize> NGBlockLayoutAlgorithm::ComputeMinMaxContentSize() 93 Optional<MinMaxContentSize> NGBlockLayoutAlgorithm::ComputeMinMaxContentSize()
95 const { 94 const {
96 MinMaxContentSize sizes; 95 MinMaxContentSize sizes;
97 96
98 // Size-contained elements don't consider their contents for intrinsic sizing. 97 // Size-contained elements don't consider their contents for intrinsic sizing.
99 if (Style().ContainsSize()) 98 if (Style().ContainsSize())
100 return sizes; 99 return sizes;
101 100
(...skipping 27 matching lines...) Expand all
129 return sizes; 128 return sizes;
130 } 129 }
131 130
132 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset( 131 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset(
133 const WTF::Optional<NGLogicalOffset>& known_fragment_offset) { 132 const WTF::Optional<NGLogicalOffset>& known_fragment_offset) {
134 LayoutUnit inline_offset = 133 LayoutUnit inline_offset =
135 border_and_padding_.inline_start + curr_child_margins_.inline_start; 134 border_and_padding_.inline_start + curr_child_margins_.inline_start;
136 LayoutUnit block_offset = content_size_; 135 LayoutUnit block_offset = content_size_;
137 if (known_fragment_offset) { 136 if (known_fragment_offset) {
138 block_offset = known_fragment_offset.value().block_offset - 137 block_offset = known_fragment_offset.value().block_offset -
139 builder_.BfcOffset().value().block_offset; 138 ContainerBfcOffset().block_offset;
140 } 139 }
141 return {inline_offset, block_offset}; 140 return {inline_offset, block_offset};
142 } 141 }
143 142
144 RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { 143 RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
145 WTF::Optional<MinMaxContentSize> min_max_size; 144 WTF::Optional<MinMaxContentSize> min_max_size;
146 if (NeedMinMaxContentSize(ConstraintSpace(), Style())) 145 if (NeedMinMaxContentSize(ConstraintSpace(), Style()))
147 min_max_size = ComputeMinMaxContentSize(); 146 min_max_size = ComputeMinMaxContentSize();
148 147
149 border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) + 148 border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) +
(...skipping 10 matching lines...) Expand all
160 // borders and padding. 159 // borders and padding.
161 NGLogicalSize adjusted_size(size); 160 NGLogicalSize adjusted_size(size);
162 if (size.block_size == NGSizeIndefinite) 161 if (size.block_size == NGSizeIndefinite)
163 adjusted_size.inline_size -= border_and_padding_.InlineSum(); 162 adjusted_size.inline_size -= border_and_padding_.InlineSum();
164 else 163 else
165 adjusted_size -= border_and_padding_; 164 adjusted_size -= border_and_padding_;
166 165
167 space_builder_.SetAvailableSize(adjusted_size) 166 space_builder_.SetAvailableSize(adjusted_size)
168 .SetPercentageResolutionSize(adjusted_size); 167 .SetPercentageResolutionSize(adjusted_size);
169 168
170 builder_.SetDirection(constraint_space_->Direction()); 169 container_builder_.SetDirection(constraint_space_->Direction());
171 builder_.SetWritingMode(constraint_space_->WritingMode()); 170 container_builder_.SetWritingMode(constraint_space_->WritingMode());
172 builder_.SetSize(size); 171 container_builder_.SetSize(size);
173 172
174 NGBlockChildIterator child_iterator(Node()->FirstChild(), BreakToken()); 173 NGBlockChildIterator child_iterator(Node()->FirstChild(), BreakToken());
175 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); 174 NGBlockChildIterator::Entry entry = child_iterator.NextChild();
176 NGLayoutInputNode* child = entry.node; 175 NGLayoutInputNode* child = entry.node;
177 NGBreakToken* child_break_token = entry.token; 176 NGBreakToken* child_break_token = entry.token;
178 177
179 // If we are resuming from a break token our start border and padding is 178 // If we are resuming from a break token our start border and padding is
180 // within a previous fragment. 179 // within a previous fragment.
181 content_size_ = BreakToken() ? LayoutUnit() : border_and_padding_.block_start; 180 content_size_ = BreakToken() ? LayoutUnit() : border_and_padding_.block_start;
182 181
183 curr_margin_strut_ = ConstraintSpace().MarginStrut(); 182 curr_margin_strut_ = ConstraintSpace().MarginStrut();
184 curr_bfc_offset_ = ConstraintSpace().BfcOffset(); 183 curr_bfc_offset_ = ConstraintSpace().BfcOffset();
185 184
186 // Margins collapsing: 185 // Margins collapsing:
187 // Do not collapse margins between parent and its child if there is 186 // Do not collapse margins between parent and its child if there is
188 // border/padding between them. 187 // border/padding between them.
189 if (border_and_padding_.block_start) { 188 if (border_and_padding_.block_start) {
190 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 189 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
191 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, 190 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
192 &builder_); 191 &container_builder_);
193 curr_margin_strut_ = NGMarginStrut(); 192 curr_margin_strut_ = NGMarginStrut();
194 } 193 }
195 194
196 // If a new formatting context hits the if branch above then the BFC offset is 195 // If a new formatting context hits the if branch above then the BFC offset is
197 // still {} as the margin strut from the constraint space must also be empty. 196 // still {} as the margin strut from the constraint space must also be empty.
198 if (ConstraintSpace().IsNewFormattingContext()) { 197 if (ConstraintSpace().IsNewFormattingContext()) {
199 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, 198 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
200 &builder_); 199 &container_builder_);
201 DCHECK_EQ(curr_margin_strut_, NGMarginStrut()); 200 DCHECK_EQ(curr_margin_strut_, NGMarginStrut());
202 DCHECK_EQ(builder_.BfcOffset().value(), NGLogicalOffset()); 201 DCHECK_EQ(container_builder_.BfcOffset().value(), NGLogicalOffset());
203 curr_bfc_offset_ = {}; 202 curr_bfc_offset_ = {};
204 } 203 }
205 204
206 curr_bfc_offset_.block_offset += content_size_; 205 curr_bfc_offset_.block_offset += content_size_;
207 206
208 while (child) { 207 while (child) {
209 if (child->IsBlock()) { 208 if (child->IsBlock()) {
210 EPosition position = child->Style().GetPosition(); 209 EPosition position = child->Style().GetPosition();
211 if (position == EPosition::kAbsolute || position == EPosition::kFixed) { 210 if (position == EPosition::kAbsolute || position == EPosition::kFixed) {
212 // TODO(ikilpatrick): curr_margin_strut_ shouldn't be included if there 211 // TODO(ikilpatrick): curr_margin_strut_ shouldn't be included if there
213 // is no content size yet? See floats-wrap-inside-inline-006. 212 // is no content size yet? See floats-wrap-inside-inline-006.
214 NGLogicalOffset offset = {border_and_padding_.inline_start, 213 NGLogicalOffset offset = {border_and_padding_.inline_start,
215 content_size_ + curr_margin_strut_.Sum()}; 214 content_size_ + curr_margin_strut_.Sum()};
216 builder_.AddOutOfFlowChildCandidate(ToNGBlockNode(child), offset); 215 container_builder_.AddOutOfFlowChildCandidate(ToNGBlockNode(child),
216 offset);
217 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); 217 NGBlockChildIterator::Entry entry = child_iterator.NextChild();
218 child = entry.node; 218 child = entry.node;
219 child_break_token = entry.token; 219 child_break_token = entry.token;
220 continue; 220 continue;
221 } 221 }
222 } 222 }
223 223
224 PrepareChildLayout(child); 224 PrepareChildLayout(child);
225 RefPtr<NGConstraintSpace> child_space = 225 RefPtr<NGConstraintSpace> child_space =
226 CreateConstraintSpaceForChild(child); 226 CreateConstraintSpaceForChild(child);
(...skipping 17 matching lines...) Expand all
244 content_size_ += border_and_padding_.block_end; 244 content_size_ += border_and_padding_.block_end;
245 if (border_and_padding_.block_end || 245 if (border_and_padding_.block_end ||
246 ConstraintSpace().IsNewFormattingContext()) { 246 ConstraintSpace().IsNewFormattingContext()) {
247 content_size_ += curr_margin_strut_.Sum(); 247 content_size_ += curr_margin_strut_.Sum();
248 curr_margin_strut_ = NGMarginStrut(); 248 curr_margin_strut_ = NGMarginStrut();
249 } 249 }
250 250
251 // Recompute the block-axis size now that we know our content size. 251 // Recompute the block-axis size now that we know our content size.
252 size.block_size = 252 size.block_size =
253 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); 253 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_);
254 builder_.SetBlockSize(size.block_size); 254 container_builder_.SetBlockSize(size.block_size);
255 255
256 // Layout our absolute and fixed positioned children. 256 // Layout our absolute and fixed positioned children.
257 NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &builder_).Run(); 257 NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &container_builder_).Run();
258 258
259 // Non-empty blocks always know their position in space: 259 // Non-empty blocks always know their position in space:
260 if (size.block_size) { 260 if (size.block_size) {
261 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 261 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
262 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, 262 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
263 &builder_); 263 &container_builder_);
264 PositionPendingFloats(curr_bfc_offset_.block_offset, 264 PositionPendingFloats(curr_bfc_offset_.block_offset,
265 MutableConstraintSpace(), &builder_); 265 MutableConstraintSpace(), &container_builder_);
266 } 266 }
267 267
268 // Margins collapsing: 268 // Margins collapsing:
269 // Do not collapse margins between the last in-flow child and bottom margin 269 // Do not collapse margins between the last in-flow child and bottom margin
270 // of its parent if the parent has height != auto() 270 // of its parent if the parent has height != auto()
271 if (!Style().LogicalHeight().IsAuto()) { 271 if (!Style().LogicalHeight().IsAuto()) {
272 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight. 272 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight.
273 curr_margin_strut_ = NGMarginStrut(); 273 curr_margin_strut_ = NGMarginStrut();
274 } 274 }
275 builder_.SetEndMarginStrut(curr_margin_strut_); 275 container_builder_.SetEndMarginStrut(curr_margin_strut_);
276 276
277 builder_.SetOverflowSize(NGLogicalSize(max_inline_size_, content_size_)); 277 container_builder_.SetOverflowSize(
278 NGLogicalSize(max_inline_size_, content_size_));
278 279
279 if (ConstraintSpace().HasBlockFragmentation()) 280 if (ConstraintSpace().HasBlockFragmentation())
280 FinalizeForFragmentation(); 281 FinalizeForFragmentation();
281 282
282 return builder_.ToBoxFragment(); 283 return container_builder_.ToBoxFragment();
283 } 284 }
284 285
285 void NGBlockLayoutAlgorithm::PrepareChildLayout(NGLayoutInputNode* child) { 286 void NGBlockLayoutAlgorithm::PrepareChildLayout(NGLayoutInputNode* child) {
286 DCHECK(child); 287 DCHECK(child);
287 288
288 // Calculate margins in parent's writing mode. 289 // Calculate margins in parent's writing mode.
289 curr_child_margins_ = CalculateMargins( 290 curr_child_margins_ = CalculateMargins(
290 child, *space_builder_.ToConstraintSpace( 291 child, *space_builder_.ToConstraintSpace(
291 FromPlatformWritingMode(Style().GetWritingMode()))); 292 FromPlatformWritingMode(Style().GetWritingMode())));
292 293
293 // Set estimated BFC offset to the next child's constraint space. 294 // Set estimated BFC offset to the next child's constraint space.
294 curr_bfc_offset_ = builder_.BfcOffset() ? builder_.BfcOffset().value() 295 curr_bfc_offset_ = container_builder_.BfcOffset()
295 : ConstraintSpace().BfcOffset(); 296 ? container_builder_.BfcOffset().value()
297 : ConstraintSpace().BfcOffset();
296 curr_bfc_offset_.block_offset += content_size_; 298 curr_bfc_offset_.block_offset += content_size_;
297 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; 299 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start;
298 300
299 bool is_floating = child->IsBlock() && child->Style().IsFloating(); 301 bool is_floating = child->IsBlock() && child->Style().IsFloating();
300 302
301 bool should_position_pending_floats = 303 bool should_position_pending_floats =
302 child->IsBlock() && !is_floating && 304 child->IsBlock() && !is_floating &&
303 !IsNewFormattingContextForBlockLevelChild(Style(), *child) && 305 !IsNewFormattingContextForBlockLevelChild(Style(), *child) &&
304 ClearanceMayAffectLayout(ConstraintSpace(), builder_.UnpositionedFloats(), 306 ClearanceMayAffectLayout(ConstraintSpace(),
307 container_builder_.UnpositionedFloats(),
305 child->Style()); 308 child->Style());
306 309
307 // Children which may clear a float need to force all the pending floats to 310 // Children which may clear a float need to force all the pending floats to
308 // be positioned before layout. This also resolves the fragment's bfc offset. 311 // be positioned before layout. This also resolves the fragment's bfc offset.
309 if (should_position_pending_floats) { 312 if (should_position_pending_floats) {
310 LayoutUnit origin_point_block_offset = 313 LayoutUnit origin_point_block_offset =
311 curr_bfc_offset_.block_offset + curr_margin_strut_.Sum(); 314 curr_bfc_offset_.block_offset + curr_margin_strut_.Sum();
312 MaybeUpdateFragmentBfcOffset( 315 MaybeUpdateFragmentBfcOffset(
313 ConstraintSpace(), 316 ConstraintSpace(),
314 {curr_bfc_offset_.inline_offset, origin_point_block_offset}, &builder_); 317 {curr_bfc_offset_.inline_offset, origin_point_block_offset},
318 &container_builder_);
315 PositionPendingFloats(origin_point_block_offset, MutableConstraintSpace(), 319 PositionPendingFloats(origin_point_block_offset, MutableConstraintSpace(),
316 &builder_); 320 &container_builder_);
317 } 321 }
318 322
319 bool is_inflow = child->IsInline() || !is_floating; 323 bool is_inflow = child->IsInline() || !is_floating;
320 324
321 // Only inflow children (e.g. not floats) are included in the child's margin 325 // Only inflow children (e.g. not floats) are included in the child's margin
322 // strut as they do not participate in margin collapsing. 326 // strut as they do not participate in margin collapsing.
323 if (is_inflow) { 327 if (is_inflow) {
324 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; 328 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start;
325 // Append the current margin strut with child's block start margin. 329 // Append the current margin strut with child's block start margin.
326 // Non empty border/padding use cases are handled inside of the child's 330 // Non empty border/padding use cases are handled inside of the child's
(...skipping 11 matching lines...) Expand all
338 child->IsInline() || 342 child->IsInline() ||
339 (!is_floating && 343 (!is_floating &&
340 IsNewFormattingContextForBlockLevelChild(Style(), *child)); 344 IsNewFormattingContextForBlockLevelChild(Style(), *child));
341 345
342 // Inline children or children which establish a block formatting context 346 // Inline children or children which establish a block formatting context
343 // collapse margins and position themselves immediately as they need to know 347 // collapse margins and position themselves immediately as they need to know
344 // their BFC offset for fragmentation purposes. 348 // their BFC offset for fragmentation purposes.
345 if (should_collapse_margins) { 349 if (should_collapse_margins) {
346 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 350 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
347 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, 351 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
348 &builder_); 352 &container_builder_);
349 PositionPendingFloats(curr_bfc_offset_.block_offset, 353 PositionPendingFloats(curr_bfc_offset_.block_offset,
350 MutableConstraintSpace(), &builder_); 354 MutableConstraintSpace(), &container_builder_);
351 curr_margin_strut_ = {}; 355 curr_margin_strut_ = {};
352 } 356 }
353 } 357 }
354 358
355 void NGBlockLayoutAlgorithm::FinishChildLayout( 359 void NGBlockLayoutAlgorithm::FinishChildLayout(
356 NGLayoutInputNode* child, 360 NGLayoutInputNode* child,
357 NGConstraintSpace* child_space, 361 NGConstraintSpace* child_space,
358 RefPtr<NGLayoutResult> layout_result) { 362 RefPtr<NGLayoutResult> layout_result) {
359 NGBoxFragment fragment( 363 NGBoxFragment fragment(
360 ConstraintSpace().WritingMode(), 364 ConstraintSpace().WritingMode(),
361 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get())); 365 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()));
362 366
363 // Pull out unpositioned floats to the current fragment. This may needed if 367 // Pull out unpositioned floats to the current fragment. This may needed if
364 // for example the child fragment could not position its floats because it's 368 // for example the child fragment could not position its floats because it's
365 // empty and therefore couldn't determine its position in space. 369 // empty and therefore couldn't determine its position in space.
366 builder_.MutableUnpositionedFloats().AppendVector( 370 container_builder_.MutableUnpositionedFloats().AppendVector(
367 layout_result->UnpositionedFloats()); 371 layout_result->UnpositionedFloats());
368 372
369 if (child->IsBlock() && child->Style().IsFloating()) { 373 if (child->IsBlock() && child->Style().IsFloating()) {
370 NGLogicalOffset origin_offset = constraint_space_->BfcOffset(); 374 NGLogicalOffset origin_offset = constraint_space_->BfcOffset();
371 origin_offset.inline_offset += border_and_padding_.inline_start; 375 origin_offset.inline_offset += border_and_padding_.inline_start;
372 RefPtr<NGFloatingObject> floating_object = NGFloatingObject::Create( 376 RefPtr<NGFloatingObject> floating_object = NGFloatingObject::Create(
373 child->Style(), child_space->WritingMode(), 377 child->Style(), child_space->WritingMode(),
374 child_space->AvailableSize(), origin_offset, 378 child_space->AvailableSize(), origin_offset,
375 constraint_space_->BfcOffset(), curr_child_margins_, 379 constraint_space_->BfcOffset(), curr_child_margins_,
376 layout_result->PhysicalFragment().Get()); 380 layout_result->PhysicalFragment().Get());
377 builder_.AddUnpositionedFloat(floating_object); 381 container_builder_.AddUnpositionedFloat(floating_object);
378 // No need to postpone the positioning if we know the correct offset. 382 // No need to postpone the positioning if we know the correct offset.
379 if (builder_.BfcOffset()) { 383 if (container_builder_.BfcOffset()) {
380 NGLogicalOffset origin_point = curr_bfc_offset_; 384 NGLogicalOffset origin_point = curr_bfc_offset_;
381 // Adjust origin point to the margins of the last child. 385 // Adjust origin point to the margins of the last child.
382 // Example: <div style="margin-bottom: 20px"><float></div> 386 // Example: <div style="margin-bottom: 20px"><float></div>
383 // <div style="margin-bottom: 30px"></div> 387 // <div style="margin-bottom: 30px"></div>
384 origin_point.block_offset += curr_margin_strut_.Sum(); 388 origin_point.block_offset += curr_margin_strut_.Sum();
385 PositionPendingFloats(origin_point.block_offset, MutableConstraintSpace(), 389 PositionPendingFloats(origin_point.block_offset, MutableConstraintSpace(),
386 &builder_); 390 &container_builder_);
387 } 391 }
388 return; 392 return;
389 } 393 }
390 394
391 // Determine the fragment's position in the parent space either by using 395 // Determine the fragment's position in the parent space either by using
392 // content_size_ or known fragment's BFC offset. 396 // content_size_ or known fragment's BFC offset.
393 WTF::Optional<NGLogicalOffset> bfc_offset; 397 WTF::Optional<NGLogicalOffset> bfc_offset;
394 if (child_space->IsNewFormattingContext()) { 398 if (child_space->IsNewFormattingContext()) {
395 DCHECK(builder_.BfcOffset());
396 bfc_offset = curr_bfc_offset_; 399 bfc_offset = curr_bfc_offset_;
397 } else if (fragment.BfcOffset()) { 400 } else if (fragment.BfcOffset()) {
398 // Fragment that knows its offset can be used to set parent's BFC position. 401 // Fragment that knows its offset can be used to set parent's BFC position.
399 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; 402 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset;
400 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, 403 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
401 &builder_); 404 &container_builder_);
402 PositionPendingFloats(curr_bfc_offset_.block_offset, 405 PositionPendingFloats(curr_bfc_offset_.block_offset,
403 MutableConstraintSpace(), &builder_); 406 MutableConstraintSpace(), &container_builder_);
404 bfc_offset = curr_bfc_offset_; 407 bfc_offset = curr_bfc_offset_;
405 } else if (builder_.BfcOffset()) { 408 } else if (container_builder_.BfcOffset()) {
406 // Fragment doesn't know its offset but we can still calculate its BFC 409 // Fragment doesn't know its offset but we can still calculate its BFC
407 // position because the parent fragment's BFC is known. 410 // position because the parent fragment's BFC is known.
408 // Example: 411 // Example:
409 // BFC Offset is known here because of the padding. 412 // BFC Offset is known here because of the padding.
410 // <div style="padding: 1px"> 413 // <div style="padding: 1px">
411 // <div id="empty-div" style="margins: 1px"></div> 414 // <div id="empty-div" style="margins: 1px"></div>
412 bfc_offset = curr_bfc_offset_; 415 bfc_offset = curr_bfc_offset_;
413 bfc_offset.value().block_offset += curr_margin_strut_.Sum(); 416 bfc_offset.value().block_offset += curr_margin_strut_.Sum();
414 } 417 }
415 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset); 418 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset);
416 419
417 // Update margin strut. 420 // Update margin strut.
418 curr_margin_strut_ = fragment.EndMarginStrut(); 421 curr_margin_strut_ = fragment.EndMarginStrut();
419 curr_margin_strut_.Append(curr_child_margins_.block_end); 422 curr_margin_strut_.Append(curr_child_margins_.block_end);
420 423
421 // Only modify content_size if BlockSize is not empty. It's needed to prevent 424 // Only modify content_size if BlockSize is not empty. It's needed to prevent
422 // the situation when logical_offset is included in content_size for empty 425 // the situation when logical_offset is included in content_size for empty
423 // blocks. Example: 426 // blocks. Example:
424 // <div style="overflow:hidden"> 427 // <div style="overflow:hidden">
425 // <div style="margin-top: 8px"></div> 428 // <div style="margin-top: 8px"></div>
426 // <div style="margin-top: 10px"></div> 429 // <div style="margin-top: 10px"></div>
427 // </div> 430 // </div>
428 if (fragment.BlockSize()) 431 if (fragment.BlockSize())
429 content_size_ = fragment.BlockSize() + logical_offset.block_offset; 432 content_size_ = fragment.BlockSize() + logical_offset.block_offset;
430 max_inline_size_ = 433 max_inline_size_ =
431 std::max(max_inline_size_, fragment.InlineSize() + 434 std::max(max_inline_size_, fragment.InlineSize() +
432 curr_child_margins_.InlineSum() + 435 curr_child_margins_.InlineSum() +
433 border_and_padding_.InlineSum()); 436 border_and_padding_.InlineSum());
434 437
435 builder_.AddChild(layout_result, logical_offset); 438 container_builder_.AddChild(layout_result, logical_offset);
436 } 439 }
437 440
438 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() { 441 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
439 LayoutUnit used_block_size = 442 LayoutUnit used_block_size =
440 BreakToken() ? BreakToken()->UsedBlockSize() : LayoutUnit(); 443 BreakToken() ? BreakToken()->UsedBlockSize() : LayoutUnit();
441 LayoutUnit block_size = ComputeBlockSizeForFragment( 444 LayoutUnit block_size = ComputeBlockSizeForFragment(
442 ConstraintSpace(), Style(), used_block_size + content_size_); 445 ConstraintSpace(), Style(), used_block_size + content_size_);
443 446
444 block_size -= used_block_size; 447 block_size -= used_block_size;
445 DCHECK_GE(block_size, LayoutUnit()) 448 DCHECK_GE(block_size, LayoutUnit())
446 << "Adding and subtracting the used_block_size shouldn't leave the " 449 << "Adding and subtracting the used_block_size shouldn't leave the "
447 "block_size for this fragment smaller than zero."; 450 "block_size for this fragment smaller than zero.";
448 451
449 DCHECK(builder_.BfcOffset()) << "We must have our BfcOffset by this point "
450 "to determine the space left in the flow.";
451 LayoutUnit space_left = ConstraintSpace().FragmentainerSpaceAvailable() - 452 LayoutUnit space_left = ConstraintSpace().FragmentainerSpaceAvailable() -
452 builder_.BfcOffset().value().block_offset; 453 ContainerBfcOffset().block_offset;
453 DCHECK_GE(space_left, LayoutUnit()); 454 DCHECK_GE(space_left, LayoutUnit());
454 455
455 if (builder_.DidBreak()) { 456 if (container_builder_.DidBreak()) {
456 // One of our children broke. Even if we fit within the remaining space we 457 // One of our children broke. Even if we fit within the remaining space we
457 // need to prepare a break token. 458 // need to prepare a break token.
458 builder_.SetUsedBlockSize(std::min(space_left, block_size) + 459 container_builder_.SetUsedBlockSize(std::min(space_left, block_size) +
459 used_block_size); 460 used_block_size);
460 builder_.SetBlockSize(std::min(space_left, block_size)); 461 container_builder_.SetBlockSize(std::min(space_left, block_size));
461 builder_.SetBlockOverflow(space_left); 462 container_builder_.SetBlockOverflow(space_left);
462 return; 463 return;
463 } 464 }
464 465
465 if (block_size > space_left) { 466 if (block_size > space_left) {
466 // Need a break inside this block. 467 // Need a break inside this block.
467 builder_.SetUsedBlockSize(space_left + used_block_size); 468 container_builder_.SetUsedBlockSize(space_left + used_block_size);
468 builder_.SetBlockSize(space_left); 469 container_builder_.SetBlockSize(space_left);
469 builder_.SetBlockOverflow(space_left); 470 container_builder_.SetBlockOverflow(space_left);
470 return; 471 return;
471 } 472 }
472 473
473 // The end of the block fits in the current fragmentainer. 474 // The end of the block fits in the current fragmentainer.
474 builder_.SetBlockSize(block_size); 475 container_builder_.SetBlockSize(block_size);
475 builder_.SetBlockOverflow(content_size_); 476 container_builder_.SetBlockOverflow(content_size_);
476 } 477 }
477 478
478 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins( 479 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
479 NGLayoutInputNode* child, 480 NGLayoutInputNode* child,
480 const NGConstraintSpace& space) { 481 const NGConstraintSpace& space) {
481 DCHECK(child); 482 DCHECK(child);
482 const ComputedStyle& child_style = child->Style(); 483 const ComputedStyle& child_style = child->Style();
483 484
484 WTF::Optional<MinMaxContentSize> sizes; 485 WTF::Optional<MinMaxContentSize> sizes;
485 if (NeedMinMaxContentSize(space, child_style)) 486 if (NeedMinMaxContentSize(space, child_style))
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 space_builder_.SetMarginStrut(child_style.IsFloating() ? NGMarginStrut() 525 space_builder_.SetMarginStrut(child_style.IsFloating() ? NGMarginStrut()
525 : curr_margin_strut_); 526 : curr_margin_strut_);
526 527
527 LayoutUnit space_available; 528 LayoutUnit space_available;
528 if (constraint_space_->HasBlockFragmentation()) { 529 if (constraint_space_->HasBlockFragmentation()) {
529 space_available = ConstraintSpace().FragmentainerSpaceAvailable(); 530 space_available = ConstraintSpace().FragmentainerSpaceAvailable();
530 // If a block establishes a new formatting context we must know our 531 // If a block establishes a new formatting context we must know our
531 // position in the formatting context, and are able to adjust the 532 // position in the formatting context, and are able to adjust the
532 // fragmentation line. 533 // fragmentation line.
533 if (is_new_bfc) { 534 if (is_new_bfc) {
534 DCHECK(builder_.BfcOffset());
535 space_available -= curr_bfc_offset_.block_offset; 535 space_available -= curr_bfc_offset_.block_offset;
536 } 536 }
537 } 537 }
538 space_builder_.SetFragmentainerSpaceAvailable(space_available); 538 space_builder_.SetFragmentainerSpaceAvailable(space_available);
539 539
540 return space_builder_.ToConstraintSpace( 540 return space_builder_.ToConstraintSpace(
541 FromPlatformWritingMode(child_style.GetWritingMode())); 541 FromPlatformWritingMode(child_style.GetWritingMode()));
542 } 542 }
543 } // namespace blink 543 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698