Index: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc |
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc |
index a7b476f4d0a6aefdc1590f2e55431bb444b59835..ab2f8a328aa1f9ab362189aca2b64aac7d4657c2 100644 |
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc |
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc |
@@ -10,6 +10,7 @@ |
#include "core/layout/ng/ng_box_fragment.h" |
#include "core/layout/ng/ng_constraint_space.h" |
#include "core/layout/ng/ng_constraint_space_builder.h" |
+#include "core/layout/ng/ng_floats_utils.h" |
#include "core/layout/ng/ng_fragment.h" |
#include "core/layout/ng/ng_fragment_builder.h" |
#include "core/layout/ng/ng_inline_node.h" |
@@ -82,157 +83,6 @@ WTF::Optional<LayoutUnit> GetClearanceOffset( |
return WTF::nullopt; |
} |
-// Creates an exclusion from the fragment that will be placed in the provided |
-// layout opportunity. |
-NGExclusion CreateExclusion(const NGFragment& fragment, |
- const NGLayoutOpportunity& opportunity, |
- const LayoutUnit float_offset, |
- const NGBoxStrut& margins, |
- NGExclusion::Type exclusion_type) { |
- NGExclusion exclusion; |
- exclusion.type = exclusion_type; |
- NGLogicalRect& rect = exclusion.rect; |
- rect.offset = opportunity.offset; |
- rect.offset.inline_offset += float_offset; |
- |
- rect.size.inline_size = fragment.InlineSize() + margins.InlineSum(); |
- rect.size.block_size = fragment.BlockSize() + margins.BlockSum(); |
- return exclusion; |
-} |
- |
-// Adjusts the provided offset to the top edge alignment rule. |
-// Top edge alignment rule: the outer top of a floating box may not be higher |
-// than the outer top of any block or floated box generated by an element |
-// earlier in the source document. |
-NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space, |
- const NGLogicalOffset& offset) { |
- NGLogicalOffset adjusted_offset = offset; |
- LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset; |
- if (space.Exclusions()->last_left_float) |
- adjusted_block_offset = |
- std::max(adjusted_block_offset, |
- space.Exclusions()->last_left_float->rect.BlockStartOffset()); |
- if (space.Exclusions()->last_right_float) |
- adjusted_block_offset = |
- std::max(adjusted_block_offset, |
- space.Exclusions()->last_right_float->rect.BlockStartOffset()); |
- return adjusted_offset; |
-} |
- |
-// Finds a layout opportunity for the fragment. |
-// It iterates over all layout opportunities in the constraint space and returns |
-// the first layout opportunity that is wider than the fragment or returns the |
-// last one which is always the widest. |
-// |
-// @param space Constraint space that is used to find layout opportunity for |
-// the fragment. |
-// @param fragment Fragment that needs to be placed. |
-// @param origin_point {@code space}'s offset relative to the space that |
-// establishes a new formatting context that we're currently |
-// in and where all our exclusions reside. |
-// @param margins Margins of the fragment. |
-// @return Layout opportunity for the fragment. |
-const NGLayoutOpportunity FindLayoutOpportunityForFragment( |
- const NGConstraintSpace* space, |
- const NGFragment& fragment, |
- const NGLogicalOffset& origin_point, |
- const NGBoxStrut& margins) { |
- NGLogicalOffset adjusted_origin_point = |
- AdjustToTopEdgeAlignmentRule(*space, origin_point); |
- |
- NGLayoutOpportunityIterator opportunity_iter(space, adjusted_origin_point); |
- NGLayoutOpportunity opportunity; |
- NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next(); |
- |
- while (!opportunity_candidate.IsEmpty()) { |
- opportunity = opportunity_candidate; |
- // Checking opportunity's block size is not necessary as a float cannot be |
- // positioned on top of another float inside of the same constraint space. |
- auto fragment_inline_size = fragment.InlineSize() + margins.InlineSum(); |
- if (opportunity.size.inline_size >= fragment_inline_size) |
- break; |
- |
- opportunity_candidate = opportunity_iter.Next(); |
- } |
- return opportunity; |
-} |
- |
-// Calculates the logical offset for opportunity. |
-NGLogicalOffset CalculateLogicalOffsetForOpportunity( |
- const NGLayoutOpportunity& opportunity, |
- const LayoutUnit float_offset, |
- const NGLogicalOffset& from_offset, |
- NGFloatingObject* floating_object) { |
- DCHECK(floating_object); |
- auto margins = floating_object->margins; |
- // Adjust to child's margin. |
- LayoutUnit inline_offset = margins.inline_start; |
- LayoutUnit block_offset = margins.block_start; |
- |
- // Offset from the opportunity's block/inline start. |
- inline_offset += opportunity.offset.inline_offset; |
- block_offset += opportunity.offset.block_offset; |
- |
- // Adjust to float: right offset if needed. |
- inline_offset += float_offset; |
- |
- block_offset -= from_offset.block_offset; |
- inline_offset -= from_offset.inline_offset; |
- |
- return NGLogicalOffset(inline_offset, block_offset); |
-} |
- |
-// Calculates the relative position from {@code from_offset} of the |
-// floating object that is requested to be positioned from {@code origin_point}. |
-NGLogicalOffset PositionFloat(const NGLogicalOffset& origin_point, |
- const NGLogicalOffset& from_offset, |
- NGFloatingObject* floating_object, |
- NGConstraintSpace* new_parent_space) { |
- DCHECK(floating_object); |
- const auto* float_space = floating_object->space.get(); |
- DCHECK(floating_object->fragment) << "Fragment cannot be null here"; |
- |
- // TODO(ikilpatrick): The writing mode switching here looks wrong. |
- NGBoxFragment float_fragment( |
- float_space->WritingMode(), |
- toNGPhysicalBoxFragment(floating_object->fragment.get())); |
- |
- // Find a layout opportunity that will fit our float. |
- const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment( |
- float_space, float_fragment, origin_point, floating_object->margins); |
- DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be"; |
- |
- // Calculate the float offset if needed. |
- LayoutUnit float_offset; |
- if (floating_object->exclusion_type == NGExclusion::kFloatRight) { |
- LayoutUnit float_margin_box_inline_size = |
- float_fragment.InlineSize() + floating_object->margins.InlineSum(); |
- float_offset = opportunity.size.inline_size - float_margin_box_inline_size; |
- } |
- |
- // Add the float as an exclusion. |
- const NGExclusion exclusion = CreateExclusion( |
- float_fragment, opportunity, float_offset, floating_object->margins, |
- floating_object->exclusion_type); |
- new_parent_space->AddExclusion(exclusion); |
- |
- return CalculateLogicalOffsetForOpportunity(opportunity, float_offset, |
- from_offset, floating_object); |
-} |
- |
-// Updates the Floating Object's left offset from the provided parent_space |
-// and {@code floating_object}'s space and margins. |
-void UpdateFloatingObjectLeftOffset(const NGConstraintSpace& new_parent_space, |
- const NGLogicalOffset& float_logical_offset, |
- NGFloatingObject* floating_object) { |
- DCHECK(floating_object); |
- // TODO(glebl): We should use physical offset here. |
- floating_object->left_offset = |
- floating_object->original_parent_space->BfcOffset().inline_offset - |
- new_parent_space.BfcOffset().inline_offset + |
- float_logical_offset.inline_offset; |
-} |
- |
// Positions pending floats stored on the fragment builder starting from |
// {@code origin_point_block_offset}. |
void PositionPendingFloats(const LayoutUnit origin_point_block_offset, |
@@ -254,8 +104,6 @@ void PositionPendingFloats(const LayoutUnit origin_point_block_offset, |
NGLogicalOffset float_fragment_offset = PositionFloat( |
origin_point, from_offset, floating_object.get(), new_parent_space); |
builder->AddFloatingObject(floating_object, float_fragment_offset); |
- UpdateFloatingObjectLeftOffset(*new_parent_space, float_fragment_offset, |
- floating_object.get()); |
} |
builder->MutableUnpositionedFloats().clear(); |
} |