Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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_floats_utils.h" | 5 #include "core/layout/ng/ng_floats_utils.h" |
| 6 | 6 |
| 7 #include "core/layout/ng/ng_box_fragment.h" | 7 #include "core/layout/ng/ng_box_fragment.h" |
| 8 #include "core/layout/ng/ng_layout_opportunity_iterator.h" | |
| 8 | 9 |
| 9 namespace blink { | 10 namespace blink { |
| 10 namespace { | 11 namespace { |
| 11 | 12 |
| 12 // Adjusts the provided offset to the top edge alignment rule. | 13 // Adjusts the provided offset to the top edge alignment rule. |
| 13 // Top edge alignment rule: the outer top of a floating box may not be higher | 14 // Top edge alignment rule: the outer top of a floating box may not be higher |
| 14 // than the outer top of any block or floated box generated by an element | 15 // than the outer top of any block or floated box generated by an element |
| 15 // earlier in the source document. | 16 // earlier in the source document. |
| 16 NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space, | 17 NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space, |
| 17 const NGLogicalOffset& offset) { | 18 const NGLogicalOffset& offset) { |
| 18 NGLogicalOffset adjusted_offset = offset; | 19 NGLogicalOffset adjusted_offset = offset; |
| 19 LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset; | 20 LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset; |
| 20 if (space.Exclusions()->last_left_float) | 21 if (space.Exclusions()->last_left_float) |
| 21 adjusted_block_offset = | 22 adjusted_block_offset = |
| 22 std::max(adjusted_block_offset, | 23 std::max(adjusted_block_offset, |
| 23 space.Exclusions()->last_left_float->rect.BlockStartOffset()); | 24 space.Exclusions()->last_left_float->rect.BlockStartOffset()); |
| 24 if (space.Exclusions()->last_right_float) | 25 if (space.Exclusions()->last_right_float) |
| 25 adjusted_block_offset = | 26 adjusted_block_offset = |
| 26 std::max(adjusted_block_offset, | 27 std::max(adjusted_block_offset, |
| 27 space.Exclusions()->last_right_float->rect.BlockStartOffset()); | 28 space.Exclusions()->last_right_float->rect.BlockStartOffset()); |
| 28 return adjusted_offset; | 29 return adjusted_offset; |
| 29 } | 30 } |
| 30 | 31 |
| 31 // Finds a layout opportunity for the fragment. | 32 // Finds a layout opportunity for the fragment. |
|
ikilpatrick
2017/04/18 13:19:55
update comments?
Gleb Lanbin
2017/04/18 17:30:20
I just deleted this comment. We don't need it anym
| |
| 32 // It iterates over all layout opportunities in the constraint space and returns | 33 // It iterates over all layout opportunities in the constraint space and returns |
| 33 // the first layout opportunity that is wider than the fragment or returns the | 34 // the first layout opportunity that is wider than the fragment or returns the |
| 34 // last one which is always the widest. | 35 // last one which is always the widest. |
| 35 // | 36 // |
| 36 // @param space Constraint space that is used to find layout opportunity for | 37 // @param space Constraint space that is used to find layout opportunity for |
| 37 // the fragment. | 38 // the fragment. |
| 38 // @param fragment Fragment that needs to be placed. | 39 // @param fragment Fragment that needs to be placed. |
| 39 // @param floating_object Floating object for which we need to find a layout | 40 // @param floating_object Floating object for which we need to find a layout |
| 40 // opportunity. | 41 // opportunity. |
| 41 // @return Layout opportunity for the fragment. | 42 // @return Layout opportunity for the fragment. |
| 42 const NGLayoutOpportunity FindLayoutOpportunityForFragment( | 43 const NGLayoutOpportunity FindLayoutOpportunityForFloat( |
| 43 const NGConstraintSpace* space, | 44 const NGConstraintSpace* space, |
| 44 const NGFragment& fragment, | 45 const NGFragment& fragment, |
| 45 const NGFloatingObject* floating_object) { | 46 const NGFloatingObject* floating_object) { |
| 46 NGLogicalOffset adjusted_origin_point = | 47 NGLogicalOffset adjusted_origin_point = |
| 47 AdjustToTopEdgeAlignmentRule(*space, floating_object->origin_offset); | 48 AdjustToTopEdgeAlignmentRule(*space, floating_object->origin_offset); |
| 48 | 49 return FindLayoutOpportunityForFragment( |
| 49 NGLayoutOpportunityIterator opportunity_iter(space->Exclusions().get(), | 50 space->Exclusions().get(), floating_object->available_size, |
| 50 floating_object->available_size, | 51 adjusted_origin_point, floating_object->margins, fragment); |
| 51 adjusted_origin_point); | |
| 52 NGLayoutOpportunity opportunity; | |
| 53 NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next(); | |
| 54 | |
| 55 NGBoxStrut margins = floating_object->margins; | |
| 56 while (!opportunity_candidate.IsEmpty()) { | |
| 57 opportunity = opportunity_candidate; | |
| 58 // Checking opportunity's block size is not necessary as a float cannot be | |
| 59 // positioned on top of another float inside of the same constraint space. | |
| 60 auto fragment_inline_size = fragment.InlineSize() + margins.InlineSum(); | |
| 61 if (opportunity.size.inline_size >= fragment_inline_size) | |
| 62 break; | |
| 63 | |
| 64 opportunity_candidate = opportunity_iter.Next(); | |
| 65 } | |
| 66 return opportunity; | |
| 67 } | 52 } |
| 68 | 53 |
| 69 // Calculates the logical offset for opportunity. | 54 // Calculates the logical offset for opportunity. |
| 70 NGLogicalOffset CalculateLogicalOffsetForOpportunity( | 55 NGLogicalOffset CalculateLogicalOffsetForOpportunity( |
| 71 const NGLayoutOpportunity& opportunity, | 56 const NGLayoutOpportunity& opportunity, |
| 72 const LayoutUnit float_offset, | 57 const LayoutUnit float_offset, |
| 73 const NGFloatingObject* floating_object) { | 58 const NGFloatingObject* floating_object) { |
| 74 DCHECK(floating_object); | 59 DCHECK(floating_object); |
| 75 auto margins = floating_object->margins; | 60 auto margins = floating_object->margins; |
| 76 // Adjust to child's margin. | 61 // Adjust to child's margin. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 NGConstraintSpace* new_parent_space) { | 106 NGConstraintSpace* new_parent_space) { |
| 122 DCHECK(floating_object); | 107 DCHECK(floating_object); |
| 123 DCHECK(floating_object->fragment) << "Fragment cannot be null here"; | 108 DCHECK(floating_object->fragment) << "Fragment cannot be null here"; |
| 124 | 109 |
| 125 // TODO(ikilpatrick): The writing mode switching here looks wrong. | 110 // TODO(ikilpatrick): The writing mode switching here looks wrong. |
| 126 NGBoxFragment float_fragment( | 111 NGBoxFragment float_fragment( |
| 127 floating_object->writing_mode, | 112 floating_object->writing_mode, |
| 128 ToNGPhysicalBoxFragment(floating_object->fragment.Get())); | 113 ToNGPhysicalBoxFragment(floating_object->fragment.Get())); |
| 129 | 114 |
| 130 // Find a layout opportunity that will fit our float. | 115 // Find a layout opportunity that will fit our float. |
| 131 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment( | 116 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat( |
| 132 new_parent_space, float_fragment, floating_object); | 117 new_parent_space, float_fragment, floating_object); |
| 133 | 118 |
| 134 // TODO(glebl): This should check for infinite opportunity instead. | 119 // TODO(glebl): This should check for infinite opportunity instead. |
| 135 if (opportunity.IsEmpty()) { | 120 if (opportunity.IsEmpty()) { |
| 136 // Because of the implementation specific of the layout opportunity iterator | 121 // Because of the implementation specific of the layout opportunity iterator |
| 137 // an empty opportunity can mean 2 things: | 122 // an empty opportunity can mean 2 things: |
| 138 // - search for layout opportunities is exhausted. | 123 // - search for layout opportunities is exhausted. |
| 139 // - opportunity has an infinite size. That's because CS is infinite. | 124 // - opportunity has an infinite size. That's because CS is infinite. |
| 140 opportunity = NGLayoutOpportunity( | 125 opportunity = NGLayoutOpportunity( |
| 141 NGLogicalOffset(), | 126 NGLogicalOffset(), |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 156 floating_object->exclusion_type); | 141 floating_object->exclusion_type); |
| 157 new_parent_space->AddExclusion(exclusion); | 142 new_parent_space->AddExclusion(exclusion); |
| 158 | 143 |
| 159 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity( | 144 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity( |
| 160 opportunity, float_offset, floating_object); | 145 opportunity, float_offset, floating_object); |
| 161 UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset, | 146 UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset, |
| 162 floating_object); | 147 floating_object); |
| 163 return logical_offset; | 148 return logical_offset; |
| 164 } | 149 } |
| 165 | 150 |
| 166 void PositionPendingFloats(const LayoutUnit& origin_block_offset, | 151 void PositionFloats(LayoutUnit origin_block_offset, |
| 167 NGConstraintSpace* space, | 152 LayoutUnit from_block_offset, |
| 168 NGFragmentBuilder* builder) { | 153 const Vector<RefPtr<NGFloatingObject>>& floating_objects, |
| 169 DCHECK(builder) << "Builder cannot be null here"; | 154 NGConstraintSpace* space) { |
| 170 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here"; | 155 for (auto& floating_object : floating_objects) { |
| 171 LayoutUnit bfc_block_offset = builder->BfcOffset().value().block_offset; | |
| 172 | |
| 173 for (auto& floating_object : builder->UnpositionedFloats()) { | |
| 174 floating_object->origin_offset.block_offset = origin_block_offset; | 156 floating_object->origin_offset.block_offset = origin_block_offset; |
| 175 floating_object->from_offset.block_offset = bfc_block_offset; | 157 floating_object->from_offset.block_offset = from_block_offset; |
| 176 | 158 floating_object->logical_offset = |
| 177 NGLogicalOffset offset = PositionFloat(floating_object.Get(), space); | 159 PositionFloat(floating_object.Get(), space); |
| 178 builder->AddFloatingObject(floating_object, offset); | |
| 179 } | 160 } |
| 180 builder->MutableUnpositionedFloats().Clear(); | |
| 181 } | 161 } |
| 182 | 162 |
| 183 } // namespace blink | 163 } // namespace blink |
| OLD | NEW |