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_block_layout_algorithm.h" | 5 #include "core/layout/ng/ng_block_layout_algorithm.h" |
6 | 6 |
7 #include "core/layout/ng/ng_absolute_utils.h" | 7 #include "core/layout/ng/ng_absolute_utils.h" |
8 #include "core/layout/ng/ng_block_break_token.h" | 8 #include "core/layout/ng/ng_block_break_token.h" |
9 #include "core/layout/ng/ng_box_fragment.h" | 9 #include "core/layout/ng/ng_box_fragment.h" |
10 #include "core/layout/ng/ng_column_mapper.h" | 10 #include "core/layout/ng/ng_column_mapper.h" |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 | 165 |
166 opportunity_candidate = opportunity_iter.Next(); | 166 opportunity_candidate = opportunity_iter.Next(); |
167 } | 167 } |
168 return opportunity; | 168 return opportunity; |
169 } | 169 } |
170 | 170 |
171 // Calculates the logical offset for opportunity. | 171 // Calculates the logical offset for opportunity. |
172 NGLogicalOffset CalculateLogicalOffsetForOpportunity( | 172 NGLogicalOffset CalculateLogicalOffsetForOpportunity( |
173 const NGLayoutOpportunity& opportunity, | 173 const NGLayoutOpportunity& opportunity, |
174 const LayoutUnit float_offset, | 174 const LayoutUnit float_offset, |
175 const NGBoxStrut& margins, | 175 const NGLogicalOffset& from_offset, |
176 const NGLogicalOffset& space_offset) { | 176 NGFloatingObject* floating_object) { |
177 auto margins = floating_object->margins; | |
177 // Adjust to child's margin. | 178 // Adjust to child's margin. |
178 LayoutUnit inline_offset = margins.inline_start; | 179 LayoutUnit inline_offset = margins.inline_start; |
179 LayoutUnit block_offset = margins.block_start; | 180 LayoutUnit block_offset = margins.block_start; |
180 | 181 |
181 // Offset from the opportunity's block/inline start. | 182 // Offset from the opportunity's block/inline start. |
182 inline_offset += opportunity.offset.inline_offset; | 183 inline_offset += opportunity.offset.inline_offset; |
183 block_offset += opportunity.offset.block_offset; | 184 block_offset += opportunity.offset.block_offset; |
184 | 185 |
186 // Adjust to float: right offset if needed. | |
185 inline_offset += float_offset; | 187 inline_offset += float_offset; |
186 | 188 |
187 block_offset -= space_offset.block_offset; | 189 block_offset -= from_offset.block_offset; |
188 inline_offset -= space_offset.inline_offset; | 190 inline_offset -= from_offset.inline_offset; |
189 | 191 |
190 return NGLogicalOffset(inline_offset, block_offset); | 192 return NGLogicalOffset(inline_offset, block_offset); |
191 } | 193 } |
192 | 194 |
193 // Calculates the relative position from {@code from_offset} of the | 195 // Calculates the relative position from {@code from_offset} of the |
194 // floating object that is requested to be positioned from {@code origin_point}. | 196 // floating object that is requested to be positioned from {@code origin_point}. |
195 NGLogicalOffset PositionFloat(const NGLogicalOffset& origin_point, | 197 NGLogicalOffset PositionFloat(const NGLogicalOffset& origin_point, |
196 const NGLogicalOffset& from_offset, | 198 const NGLogicalOffset& from_offset, |
197 NGFloatingObject* floating_object) { | 199 NGFloatingObject* floating_object) { |
198 NGConstraintSpace* float_space = floating_object->space; | 200 NGConstraintSpace* float_space = floating_object->space; |
(...skipping 15 matching lines...) Expand all Loading... | |
214 if (floating_object->exclusion_type == NGExclusion::kFloatRight) { | 216 if (floating_object->exclusion_type == NGExclusion::kFloatRight) { |
215 float_offset = opportunity.size.inline_size - float_fragment.InlineSize(); | 217 float_offset = opportunity.size.inline_size - float_fragment.InlineSize(); |
216 } | 218 } |
217 | 219 |
218 // Add the float as an exclusion. | 220 // Add the float as an exclusion. |
219 const NGExclusion exclusion = CreateExclusion( | 221 const NGExclusion exclusion = CreateExclusion( |
220 float_fragment, opportunity, float_offset, floating_object->margins, | 222 float_fragment, opportunity, float_offset, floating_object->margins, |
221 floating_object->exclusion_type); | 223 floating_object->exclusion_type); |
222 float_space->AddExclusion(exclusion); | 224 float_space->AddExclusion(exclusion); |
223 | 225 |
224 return CalculateLogicalOffsetForOpportunity( | 226 return CalculateLogicalOffsetForOpportunity(opportunity, float_offset, |
225 opportunity, float_offset, floating_object->margins, from_offset); | 227 from_offset, floating_object); |
228 } | |
229 | |
230 // Updates the Floating Object's left offset from the provided parent_space and | |
231 // {@code floating_object}'s space and margins. | |
232 void UpdateFloatingObjectLeftOffset( | |
cbiesinger
2017/02/08 22:39:01
Left -> Inline, no?
Gleb Lanbin
2017/02/09 18:39:25
you're right. We should use physical coordinates h
| |
233 const NGConstraintSpace& parent_space, | |
234 const Persistent<NGFloatingObject>& floating_object) { | |
235 const auto& float_space = floating_object->space; | |
236 floating_object->left_offset = float_space->BfcOffset().inline_offset - | |
237 parent_space.BfcOffset().inline_offset + | |
238 floating_object->margins.inline_start; | |
226 } | 239 } |
227 | 240 |
228 // Positions pending floats stored on the fragment builder starting from | 241 // Positions pending floats stored on the fragment builder starting from |
229 // {@code origin_point}. | 242 // {@code origin_point_block_offset}. |
230 void PositionPendingFloats(const NGLogicalOffset& origin_point, | 243 void PositionPendingFloats(const LayoutUnit origin_point_block_offset, |
244 const NGConstraintSpace& parent_space, | |
231 NGFragmentBuilder* builder) { | 245 NGFragmentBuilder* builder) { |
232 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here"; | 246 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here"; |
233 NGLogicalOffset from_offset = builder->BfcOffset().value(); | 247 LayoutUnit from_offset_block_offset = |
cbiesinger
2017/02/08 22:39:01
I think "from_offset_block" reads better
Gleb Lanbin
2017/02/09 18:39:25
Done.
| |
248 builder->BfcOffset().value().block_offset; | |
234 | 249 |
235 for (auto& floating_object : builder->UnpositionedFloats()) { | 250 for (auto& floating_object : builder->UnpositionedFloats()) { |
251 auto float_space = floating_object->space; | |
cbiesinger
2017/02/08 22:39:01
auto*
Gleb Lanbin
2017/02/09 18:39:25
done. it's Member<const NGConstraintSpace> which i
| |
252 auto float_parent_space = floating_object->parent_space; | |
253 | |
254 NGLogicalOffset origin_point = {float_space->BfcOffset().inline_offset, | |
255 origin_point_block_offset}; | |
256 NGLogicalOffset from_offset = { | |
257 float_parent_space->BfcOffset().inline_offset, | |
258 from_offset_block_offset}; | |
259 | |
236 NGLogicalOffset float_fragment_offset = | 260 NGLogicalOffset float_fragment_offset = |
237 PositionFloat(origin_point, from_offset, floating_object); | 261 PositionFloat(origin_point, from_offset, floating_object); |
238 builder->AddFloatingObject(floating_object, float_fragment_offset); | 262 builder->AddFloatingObject(floating_object, float_fragment_offset); |
263 UpdateFloatingObjectLeftOffset(parent_space, floating_object); | |
239 } | 264 } |
240 builder->MutableUnpositionedFloats().clear(); | 265 builder->MutableUnpositionedFloats().clear(); |
241 } | 266 } |
242 | 267 |
243 // Whether an in-flow block-level child creates a new formatting context. | 268 // Whether an in-flow block-level child creates a new formatting context. |
244 // | 269 // |
245 // This will *NOT* check the following cases: | 270 // This will *NOT* check the following cases: |
246 // - The child is out-of-flow, e.g. floating or abs-pos. | 271 // - The child is out-of-flow, e.g. floating or abs-pos. |
247 // - The child is a inline-level, e.g. "display: inline-block". | 272 // - The child is a inline-level, e.g. "display: inline-block". |
248 // - The child establishes a new formatting context, but should be a child of | 273 // - The child establishes a new formatting context, but should be a child of |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
451 builder_->SetBlockSize(block_size); | 476 builder_->SetBlockSize(block_size); |
452 | 477 |
453 // Layout our absolute and fixed positioned children. | 478 // Layout our absolute and fixed positioned children. |
454 NGOutOfFlowLayoutPart(Style(), builder_.get()).Run(); | 479 NGOutOfFlowLayoutPart(Style(), builder_.get()).Run(); |
455 | 480 |
456 // Non empty blocks always know their position in space: | 481 // Non empty blocks always know their position in space: |
457 if (block_size) { | 482 if (block_size) { |
458 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); | 483 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); |
459 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), | 484 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), |
460 builder_.get()); | 485 builder_.get()); |
461 PositionPendingFloats(curr_bfc_offset_, builder_.get()); | 486 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), |
487 builder_.get()); | |
462 } | 488 } |
463 | 489 |
464 // Margins collapsing: | 490 // Margins collapsing: |
465 // Do not collapse margins between the last in-flow child and bottom margin | 491 // Do not collapse margins between the last in-flow child and bottom margin |
466 // of its parent if the parent has height != auto() | 492 // of its parent if the parent has height != auto() |
467 if (!Style().logicalHeight().isAuto()) { | 493 if (!Style().logicalHeight().isAuto()) { |
468 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight. | 494 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight. |
469 curr_margin_strut_ = NGMarginStrut(); | 495 curr_margin_strut_ = NGMarginStrut(); |
470 } | 496 } |
471 builder_->SetEndMarginStrut(curr_margin_strut_); | 497 builder_->SetEndMarginStrut(curr_margin_strut_); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 // Pull out unpositioned floats to the current fragment. This may needed if | 531 // Pull out unpositioned floats to the current fragment. This may needed if |
506 // for example the child fragment could not position its floats because it's | 532 // for example the child fragment could not position its floats because it's |
507 // empty and therefore couldn't determine its position in space. | 533 // empty and therefore couldn't determine its position in space. |
508 builder_->MutableUnpositionedFloats().appendVector( | 534 builder_->MutableUnpositionedFloats().appendVector( |
509 physical_fragment->UnpositionedFloats()); | 535 physical_fragment->UnpositionedFloats()); |
510 | 536 |
511 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock && | 537 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock && |
512 CurrentChildStyle().isFloating()) { | 538 CurrentChildStyle().isFloating()) { |
513 NGFloatingObject* floating_object = | 539 NGFloatingObject* floating_object = |
514 new NGFloatingObject(physical_fragment.get(), space_for_current_child_, | 540 new NGFloatingObject(physical_fragment.get(), space_for_current_child_, |
515 toNGBlockNode(current_child_), CurrentChildStyle(), | 541 constraint_space_, toNGBlockNode(current_child_), |
516 curr_child_margins_); | 542 CurrentChildStyle(), curr_child_margins_); |
517 builder_->AddUnpositionedFloat(floating_object); | 543 builder_->AddUnpositionedFloat(floating_object); |
518 // No need to postpone the positioning if we know the correct offset. | 544 // No need to postpone the positioning if we know the correct offset. |
519 if (builder_->BfcOffset()) { | 545 if (builder_->BfcOffset()) { |
520 NGLogicalOffset origin_point = curr_bfc_offset_; | 546 NGLogicalOffset origin_point = curr_bfc_offset_; |
521 // Adjust origin point to the margins of the last child. | 547 // Adjust origin point to the margins of the last child. |
522 // Example: <div style="margin-bottom: 20px"><float></div> | 548 // Example: <div style="margin-bottom: 20px"><float></div> |
523 // <div style="margin-bottom: 30px"></div> | 549 // <div style="margin-bottom: 30px"></div> |
524 origin_point.block_offset += curr_margin_strut_.Sum(); | 550 origin_point.block_offset += curr_margin_strut_.Sum(); |
525 PositionPendingFloats(origin_point, builder_.get()); | 551 PositionPendingFloats(origin_point.block_offset, ConstraintSpace(), |
552 builder_.get()); | |
526 } | 553 } |
527 return; | 554 return; |
528 } | 555 } |
529 | 556 |
530 // Fragment that knows its offset can be used to set parent's BFC position. | 557 // Fragment that knows its offset can be used to set parent's BFC position. |
531 if (fragment.BfcOffset()) { | 558 if (fragment.BfcOffset()) { |
532 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; | 559 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; |
533 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), | 560 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), |
534 builder_.get()); | 561 builder_.get()); |
535 PositionPendingFloats(curr_bfc_offset_, builder_.get()); | 562 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), |
563 builder_.get()); | |
536 } | 564 } |
537 NGLogicalOffset fragment_offset = CalculateRelativeOffset(fragment); | 565 NGLogicalOffset fragment_offset = CalculateRelativeOffset(fragment); |
538 | 566 |
539 if (fragmentainer_mapper_) | 567 if (fragmentainer_mapper_) |
540 fragmentainer_mapper_->ToVisualOffset(fragment_offset); | 568 fragmentainer_mapper_->ToVisualOffset(fragment_offset); |
541 else | 569 else |
542 fragment_offset.block_offset -= PreviousBreakOffset(); | 570 fragment_offset.block_offset -= PreviousBreakOffset(); |
543 | 571 |
544 // Update margin strut. | 572 // Update margin strut. |
545 curr_margin_strut_ = fragment.EndMarginStrut(); | 573 curr_margin_strut_ = fragment.EndMarginStrut(); |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
749 // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847 | 777 // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847 |
750 if (current_child_style.clear() != EClear::kNone) { | 778 if (current_child_style.clear() != EClear::kNone) { |
751 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); | 779 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); |
752 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), | 780 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), |
753 builder_.get()); | 781 builder_.get()); |
754 // Only collapse margins if it's an adjoining block with clearance. | 782 // Only collapse margins if it's an adjoining block with clearance. |
755 if (!content_size_) { | 783 if (!content_size_) { |
756 curr_margin_strut_ = NGMarginStrut(); | 784 curr_margin_strut_ = NGMarginStrut(); |
757 curr_child_margins_.block_start = LayoutUnit(); | 785 curr_child_margins_.block_start = LayoutUnit(); |
758 } | 786 } |
759 PositionPendingFloats(curr_bfc_offset_, builder_.get()); | 787 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), |
788 builder_.get()); | |
760 AdjustToClearance(constraint_space_->Exclusions(), current_child_style, | 789 AdjustToClearance(constraint_space_->Exclusions(), current_child_style, |
761 builder_->BfcOffset().value(), &content_size_); | 790 builder_->BfcOffset().value(), &content_size_); |
762 } | 791 } |
763 | 792 |
764 // Append the current margin strut with child's block start margin. | 793 // Append the current margin strut with child's block start margin. |
765 // Non empty border/padding use cases are handled inside of the child's | 794 // Non empty border/padding use cases are handled inside of the child's |
766 // layout. | 795 // layout. |
767 curr_margin_strut_.Append(curr_child_margins_.block_start); | 796 curr_margin_strut_.Append(curr_child_margins_.block_start); |
768 space_builder_->SetMarginStrut(curr_margin_strut_); | 797 space_builder_->SetMarginStrut(curr_margin_strut_); |
769 | 798 |
770 // Set estimated BFC offset to the next child's constraint space. | 799 // Set estimated BFC offset to the next child's constraint space. |
771 curr_bfc_offset_ = builder_->BfcOffset() ? builder_->BfcOffset().value() | 800 curr_bfc_offset_ = builder_->BfcOffset() ? builder_->BfcOffset().value() |
772 : ConstraintSpace().BfcOffset(); | 801 : ConstraintSpace().BfcOffset(); |
773 curr_bfc_offset_.block_offset += content_size_; | 802 curr_bfc_offset_.block_offset += content_size_; |
774 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; | 803 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; |
775 if (ConstraintSpace().IsNewFormattingContext()) { | 804 |
805 if (!CurrentChildStyle().isFloating()) { | |
776 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; | 806 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; |
777 } | 807 } |
808 | |
778 space_builder_->SetBfcOffset(curr_bfc_offset_); | 809 space_builder_->SetBfcOffset(curr_bfc_offset_); |
779 | 810 |
780 return space_builder_->ToConstraintSpace(); | 811 return space_builder_->ToConstraintSpace(); |
781 } | 812 } |
782 | 813 |
783 } // namespace blink | 814 } // namespace blink |
OLD | NEW |