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 |