| 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_constraint_space_builder.h" | 8 #include "core/layout/ng/ng_constraint_space_builder.h" |
| 9 #include "core/layout/ng/ng_layout_opportunity_iterator.h" | 9 #include "core/layout/ng/ng_layout_opportunity_iterator.h" |
| 10 #include "core/layout/ng/ng_layout_result.h" | 10 #include "core/layout/ng/ng_layout_result.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 std::max(adjusted_block_offset, | 28 std::max(adjusted_block_offset, |
| 29 space.Exclusions()->last_left_float->rect.BlockStartOffset()); | 29 space.Exclusions()->last_left_float->rect.BlockStartOffset()); |
| 30 if (space.Exclusions()->last_right_float) | 30 if (space.Exclusions()->last_right_float) |
| 31 adjusted_block_offset = | 31 adjusted_block_offset = |
| 32 std::max(adjusted_block_offset, | 32 std::max(adjusted_block_offset, |
| 33 space.Exclusions()->last_right_float->rect.BlockStartOffset()); | 33 space.Exclusions()->last_right_float->rect.BlockStartOffset()); |
| 34 return adjusted_offset; | 34 return adjusted_offset; |
| 35 } | 35 } |
| 36 | 36 |
| 37 NGLayoutOpportunity FindLayoutOpportunityForFloat( | 37 NGLayoutOpportunity FindLayoutOpportunityForFloat( |
| 38 const NGLogicalOffset& origin_offset, |
| 38 const NGConstraintSpace& space, | 39 const NGConstraintSpace& space, |
| 39 const NGUnpositionedFloat& unpositioned_float, | 40 const NGUnpositionedFloat& unpositioned_float, |
| 40 LayoutUnit inline_size) { | 41 LayoutUnit inline_size) { |
| 41 NGLogicalOffset adjusted_origin_point = | 42 NGLogicalOffset adjusted_origin_point = |
| 42 AdjustToTopEdgeAlignmentRule(space, unpositioned_float.origin_offset); | 43 AdjustToTopEdgeAlignmentRule(space, origin_offset); |
| 43 WTF::Optional<LayoutUnit> clearance_offset = | 44 WTF::Optional<LayoutUnit> clearance_offset = |
| 44 GetClearanceOffset(space.Exclusions(), unpositioned_float.ClearType()); | 45 GetClearanceOffset(space.Exclusions(), unpositioned_float.ClearType()); |
| 45 | 46 |
| 46 AdjustToClearance(clearance_offset, &adjusted_origin_point); | 47 AdjustToClearance(clearance_offset, &adjusted_origin_point); |
| 47 | 48 |
| 48 return FindLayoutOpportunityForFragment( | 49 return FindLayoutOpportunityForFragment( |
| 49 space.Exclusions().get(), unpositioned_float.available_size, | 50 space.Exclusions().get(), unpositioned_float.available_size, |
| 50 adjusted_origin_point, unpositioned_float.margins, | 51 adjusted_origin_point, unpositioned_float.margins, |
| 51 {inline_size, LayoutUnit()}); | 52 {inline_size, LayoutUnit()}); |
| 52 } | 53 } |
| 53 | 54 |
| 54 // Calculates the logical offset for opportunity. | 55 // Calculates the logical offset for opportunity. |
| 55 NGLogicalOffset CalculateLogicalOffsetForOpportunity( | 56 NGLogicalOffset CalculateLogicalOffsetForOpportunity( |
| 56 const NGLayoutOpportunity& opportunity, | 57 const NGLayoutOpportunity& opportunity, |
| 57 const LayoutUnit float_offset, | 58 const LayoutUnit float_offset, |
| 59 const LayoutUnit parent_bfc_block_offset, |
| 58 const NGUnpositionedFloat* unpositioned_float) { | 60 const NGUnpositionedFloat* unpositioned_float) { |
| 59 DCHECK(unpositioned_float); | 61 DCHECK(unpositioned_float); |
| 60 auto margins = unpositioned_float->margins; | 62 auto margins = unpositioned_float->margins; |
| 61 // Adjust to child's margin. | 63 // Adjust to child's margin. |
| 62 NGLogicalOffset result = margins.InlineBlockStartOffset(); | 64 NGLogicalOffset result = margins.InlineBlockStartOffset(); |
| 63 | 65 |
| 64 // Offset from the opportunity's block/inline start. | 66 // Offset from the opportunity's block/inline start. |
| 65 result += opportunity.offset; | 67 result += opportunity.offset; |
| 66 | 68 |
| 67 // Adjust to float: right offset if needed. | 69 // Adjust to float: right offset if needed. |
| 68 result.inline_offset += float_offset; | 70 result.inline_offset += float_offset; |
| 69 | 71 |
| 70 result -= unpositioned_float->from_offset; | 72 result -= {unpositioned_float->bfc_inline_offset, parent_bfc_block_offset}; |
| 73 |
| 71 return result; | 74 return result; |
| 72 } | 75 } |
| 73 | 76 |
| 74 // Creates an exclusion from the fragment that will be placed in the provided | 77 // Creates an exclusion from the fragment that will be placed in the provided |
| 75 // layout opportunity. | 78 // layout opportunity. |
| 76 NGExclusion CreateExclusion(const NGFragment& fragment, | 79 NGExclusion CreateExclusion(const NGFragment& fragment, |
| 77 const NGLayoutOpportunity& opportunity, | 80 const NGLayoutOpportunity& opportunity, |
| 78 const LayoutUnit float_offset, | 81 const LayoutUnit float_offset, |
| 79 const NGBoxStrut& margins, | 82 const NGBoxStrut& margins, |
| 80 NGExclusion::Type exclusion_type) { | 83 NGExclusion::Type exclusion_type) { |
| 81 NGExclusion exclusion; | 84 NGExclusion exclusion; |
| 82 exclusion.type = exclusion_type; | 85 exclusion.type = exclusion_type; |
| 83 NGLogicalRect& rect = exclusion.rect; | 86 NGLogicalRect& rect = exclusion.rect; |
| 84 rect.offset = opportunity.offset; | 87 rect.offset = opportunity.offset; |
| 85 rect.offset.inline_offset += float_offset; | 88 rect.offset.inline_offset += float_offset; |
| 86 | 89 |
| 87 rect.size.inline_size = fragment.InlineSize() + margins.InlineSum(); | 90 rect.size.inline_size = fragment.InlineSize() + margins.InlineSum(); |
| 88 rect.size.block_size = fragment.BlockSize() + margins.BlockSum(); | 91 rect.size.block_size = fragment.BlockSize() + margins.BlockSum(); |
| 89 return exclusion; | 92 return exclusion; |
| 90 } | 93 } |
| 91 | 94 |
| 92 // Updates the Floating object's offsets. | 95 // Updates the Floating object's offsets. |
| 93 NGLogicalOffset CalculateFloatingObjectPaintOffset( | 96 NGLogicalOffset CalculateFloatingObjectPaintOffset( |
| 94 const NGConstraintSpace& new_parent_space, | 97 const NGConstraintSpace& new_parent_space, |
| 95 const NGLogicalOffset& float_logical_offset, | 98 const NGLogicalOffset& float_logical_offset, |
| 96 const NGUnpositionedFloat& unpositioned_float) { | 99 const NGUnpositionedFloat& unpositioned_float) { |
| 97 LayoutUnit inline_offset = unpositioned_float.from_offset.inline_offset - | 100 LayoutUnit inline_offset = unpositioned_float.bfc_inline_offset - |
| 98 new_parent_space.BfcOffset().inline_offset + | 101 new_parent_space.BfcOffset().inline_offset + |
| 99 float_logical_offset.inline_offset; | 102 float_logical_offset.inline_offset; |
| 100 DCHECK(unpositioned_float.parent_bfc_block_offset); | 103 LayoutUnit block_offset = float_logical_offset.block_offset; |
| 101 LayoutUnit block_offset = unpositioned_float.from_offset.block_offset - | |
| 102 unpositioned_float.parent_bfc_block_offset.value() + | |
| 103 float_logical_offset.block_offset; | |
| 104 return {inline_offset, block_offset}; | 104 return {inline_offset, block_offset}; |
| 105 } | 105 } |
| 106 | 106 |
| 107 // TODO(ikilpatrick): origin_block_offset looks wrong for fragmentation here. |
| 107 WTF::Optional<LayoutUnit> CalculateFragmentationOffset( | 108 WTF::Optional<LayoutUnit> CalculateFragmentationOffset( |
| 109 const LayoutUnit origin_block_offset, |
| 108 const NGUnpositionedFloat& unpositioned_float, | 110 const NGUnpositionedFloat& unpositioned_float, |
| 109 const NGConstraintSpace& parent_space) { | 111 const NGConstraintSpace& parent_space) { |
| 110 const ComputedStyle& style = unpositioned_float.node.Style(); | 112 const ComputedStyle& style = unpositioned_float.node.Style(); |
| 111 DCHECK(FromPlatformWritingMode(style.GetWritingMode()) == | 113 DCHECK(FromPlatformWritingMode(style.GetWritingMode()) == |
| 112 parent_space.WritingMode()); | 114 parent_space.WritingMode()); |
| 113 | 115 |
| 114 if (parent_space.HasBlockFragmentation()) { | 116 if (parent_space.HasBlockFragmentation()) { |
| 115 return parent_space.FragmentainerSpaceAvailable() - | 117 return parent_space.FragmentainerSpaceAvailable() - origin_block_offset; |
| 116 unpositioned_float.origin_offset.block_offset; | |
| 117 } | 118 } |
| 118 | 119 |
| 119 return WTF::nullopt; | 120 return WTF::nullopt; |
| 120 } | 121 } |
| 121 | 122 |
| 122 // Creates a constraint space for an unpositioned float. | 123 // Creates a constraint space for an unpositioned float. |
| 123 RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat( | 124 RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat( |
| 124 const NGUnpositionedFloat& unpositioned_float, | 125 const NGUnpositionedFloat& unpositioned_float, |
| 125 NGConstraintSpace* parent_space, | 126 NGConstraintSpace* parent_space, |
| 126 WTF::Optional<LayoutUnit> fragmentation_offset = WTF::nullopt) { | 127 WTF::Optional<LayoutUnit> fragmentation_offset = WTF::nullopt) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 RefPtr<NGPhysicalBoxFragment> fragment = | 192 RefPtr<NGPhysicalBoxFragment> fragment = |
| 192 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()); | 193 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()); |
| 193 unpositioned_float->fragment = fragment; | 194 unpositioned_float->fragment = fragment; |
| 194 | 195 |
| 195 DCHECK(fragment->BreakToken()->IsFinished()); | 196 DCHECK(fragment->BreakToken()->IsFinished()); |
| 196 | 197 |
| 197 return NGBoxFragment(parent_space->WritingMode(), fragment.Get()) | 198 return NGBoxFragment(parent_space->WritingMode(), fragment.Get()) |
| 198 .InlineSize(); | 199 .InlineSize(); |
| 199 } | 200 } |
| 200 | 201 |
| 201 NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float, | 202 NGPositionedFloat PositionFloat(LayoutUnit origin_block_offset, |
| 203 LayoutUnit parent_bfc_block_offset, |
| 204 NGUnpositionedFloat* unpositioned_float, |
| 202 NGConstraintSpace* new_parent_space) { | 205 NGConstraintSpace* new_parent_space) { |
| 203 DCHECK(unpositioned_float); | 206 DCHECK(unpositioned_float); |
| 204 LayoutUnit inline_size = ComputeInlineSizeForUnpositionedFloat( | 207 LayoutUnit inline_size = ComputeInlineSizeForUnpositionedFloat( |
| 205 new_parent_space, unpositioned_float); | 208 new_parent_space, unpositioned_float); |
| 206 | 209 |
| 210 NGLogicalOffset origin_offset = {unpositioned_float->origin_bfc_inline_offset, |
| 211 origin_block_offset}; |
| 212 |
| 207 // Find a layout opportunity that will fit our float. | 213 // Find a layout opportunity that will fit our float. |
| 208 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat( | 214 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat( |
| 209 *new_parent_space, *unpositioned_float, inline_size); | 215 origin_offset, *new_parent_space, *unpositioned_float, inline_size); |
| 210 | 216 |
| 211 #if DCHECK_IS_ON() | 217 #if DCHECK_IS_ON() |
| 212 bool is_same_writing_mode = | 218 bool is_same_writing_mode = |
| 213 FromPlatformWritingMode( | 219 FromPlatformWritingMode( |
| 214 unpositioned_float->node.Style().GetWritingMode()) == | 220 unpositioned_float->node.Style().GetWritingMode()) == |
| 215 new_parent_space->WritingMode(); | 221 new_parent_space->WritingMode(); |
| 216 #endif | 222 #endif |
| 217 | 223 |
| 218 RefPtr<NGPhysicalBoxFragment> physical_fragment; | 224 RefPtr<NGPhysicalBoxFragment> physical_fragment; |
| 219 // We should only have a fragment if its writing mode is different, i.e. it | 225 // We should only have a fragment if its writing mode is different, i.e. it |
| 220 // can't fragment. | 226 // can't fragment. |
| 221 if (unpositioned_float->fragment) { | 227 if (unpositioned_float->fragment) { |
| 222 #if DCHECK_IS_ON() | 228 #if DCHECK_IS_ON() |
| 223 DCHECK(!is_same_writing_mode); | 229 DCHECK(!is_same_writing_mode); |
| 224 #endif | 230 #endif |
| 225 physical_fragment = unpositioned_float->fragment.value(); | 231 physical_fragment = unpositioned_float->fragment.value(); |
| 226 } else { | 232 } else { |
| 227 #if DCHECK_IS_ON() | 233 #if DCHECK_IS_ON() |
| 228 DCHECK(is_same_writing_mode); | 234 DCHECK(is_same_writing_mode); |
| 229 #endif | 235 #endif |
| 230 WTF::Optional<LayoutUnit> fragmentation_offset = | 236 WTF::Optional<LayoutUnit> fragmentation_offset = |
| 231 CalculateFragmentationOffset(*unpositioned_float, *new_parent_space); | 237 CalculateFragmentationOffset(origin_block_offset, *unpositioned_float, |
| 238 *new_parent_space); |
| 232 | 239 |
| 233 RefPtr<NGConstraintSpace> space = CreateConstraintSpaceForFloat( | 240 RefPtr<NGConstraintSpace> space = CreateConstraintSpaceForFloat( |
| 234 *unpositioned_float, new_parent_space, fragmentation_offset); | 241 *unpositioned_float, new_parent_space, fragmentation_offset); |
| 235 RefPtr<NGLayoutResult> layout_result = unpositioned_float->node.Layout( | 242 RefPtr<NGLayoutResult> layout_result = unpositioned_float->node.Layout( |
| 236 space.Get(), unpositioned_float->token.Get()); | 243 space.Get(), unpositioned_float->token.Get()); |
| 237 physical_fragment = | 244 physical_fragment = |
| 238 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()); | 245 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()); |
| 239 } | 246 } |
| 240 | 247 |
| 241 NGBoxFragment float_fragment(new_parent_space->WritingMode(), | 248 NGBoxFragment float_fragment(new_parent_space->WritingMode(), |
| (...skipping 19 matching lines...) Expand all Loading... |
| 261 } | 268 } |
| 262 | 269 |
| 263 // Add the float as an exclusion. | 270 // Add the float as an exclusion. |
| 264 const NGExclusion exclusion = CreateExclusion( | 271 const NGExclusion exclusion = CreateExclusion( |
| 265 float_fragment, opportunity, float_offset, unpositioned_float->margins, | 272 float_fragment, opportunity, float_offset, unpositioned_float->margins, |
| 266 unpositioned_float->IsRight() ? NGExclusion::Type::kFloatRight | 273 unpositioned_float->IsRight() ? NGExclusion::Type::kFloatRight |
| 267 : NGExclusion::Type::kFloatLeft); | 274 : NGExclusion::Type::kFloatLeft); |
| 268 new_parent_space->AddExclusion(exclusion); | 275 new_parent_space->AddExclusion(exclusion); |
| 269 | 276 |
| 270 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity( | 277 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity( |
| 271 opportunity, float_offset, unpositioned_float); | 278 opportunity, float_offset, parent_bfc_block_offset, unpositioned_float); |
| 272 NGLogicalOffset paint_offset = CalculateFloatingObjectPaintOffset( | 279 NGLogicalOffset paint_offset = CalculateFloatingObjectPaintOffset( |
| 273 *new_parent_space, logical_offset, *unpositioned_float); | 280 *new_parent_space, logical_offset, *unpositioned_float); |
| 274 | 281 |
| 275 return NGPositionedFloat(std::move(physical_fragment), logical_offset, | 282 return NGPositionedFloat(std::move(physical_fragment), logical_offset, |
| 276 paint_offset); | 283 paint_offset); |
| 277 } | 284 } |
| 278 | 285 |
| 279 const Vector<NGPositionedFloat> PositionFloats( | 286 const Vector<NGPositionedFloat> PositionFloats( |
| 280 LayoutUnit origin_block_offset, | 287 LayoutUnit origin_block_offset, |
| 281 LayoutUnit from_block_offset, | 288 LayoutUnit parent_bfc_block_offset, |
| 282 LayoutUnit parent_bfc_offset, | |
| 283 const Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats, | 289 const Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats, |
| 284 NGConstraintSpace* space) { | 290 NGConstraintSpace* space) { |
| 285 Vector<NGPositionedFloat> positioned_floats; | 291 Vector<NGPositionedFloat> positioned_floats; |
| 286 positioned_floats.ReserveCapacity(unpositioned_floats.size()); | 292 positioned_floats.ReserveCapacity(unpositioned_floats.size()); |
| 287 | 293 |
| 288 for (auto& unpositioned_float : unpositioned_floats) { | 294 for (auto& unpositioned_float : unpositioned_floats) { |
| 289 unpositioned_float->origin_offset.block_offset = origin_block_offset; | 295 positioned_floats.push_back(PositionFloat(origin_block_offset, |
| 290 unpositioned_float->from_offset.block_offset = from_block_offset; | 296 parent_bfc_block_offset, |
| 291 unpositioned_float->parent_bfc_block_offset = parent_bfc_offset; | 297 unpositioned_float.Get(), space)); |
| 292 positioned_floats.push_back(PositionFloat(unpositioned_float.Get(), space)); | |
| 293 } | 298 } |
| 294 | 299 |
| 295 return positioned_floats; | 300 return positioned_floats; |
| 296 } | 301 } |
| 297 | 302 |
| 298 } // namespace blink | 303 } // namespace blink |
| OLD | NEW |