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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 DCHECK(unpositioned_float.parent_bfc_block_offset); | 101 DCHECK(unpositioned_float.parent_bfc_block_offset); |
102 LayoutUnit top_offset = unpositioned_float.from_offset.block_offset - | 102 LayoutUnit top_offset = unpositioned_float.from_offset.block_offset - |
103 unpositioned_float.parent_bfc_block_offset.value() + | 103 unpositioned_float.parent_bfc_block_offset.value() + |
104 float_logical_offset.block_offset; | 104 float_logical_offset.block_offset; |
105 return {left_offset, top_offset}; | 105 return {left_offset, top_offset}; |
106 } | 106 } |
107 | 107 |
108 WTF::Optional<LayoutUnit> CalculateFragmentationOffset( | 108 WTF::Optional<LayoutUnit> CalculateFragmentationOffset( |
109 const NGUnpositionedFloat& unpositioned_float, | 109 const NGUnpositionedFloat& unpositioned_float, |
110 const NGConstraintSpace& parent_space) { | 110 const NGConstraintSpace& parent_space) { |
111 const ComputedStyle& style = unpositioned_float.node->Style(); | 111 const ComputedStyle& style = unpositioned_float.node.Style(); |
112 DCHECK(FromPlatformWritingMode(style.GetWritingMode()) == | 112 DCHECK(FromPlatformWritingMode(style.GetWritingMode()) == |
113 parent_space.WritingMode()); | 113 parent_space.WritingMode()); |
114 | 114 |
115 if (parent_space.HasBlockFragmentation()) { | 115 if (parent_space.HasBlockFragmentation()) { |
116 return parent_space.FragmentainerSpaceAvailable() - | 116 return parent_space.FragmentainerSpaceAvailable() - |
117 unpositioned_float.origin_offset.block_offset; | 117 unpositioned_float.origin_offset.block_offset; |
118 } | 118 } |
119 | 119 |
120 return WTF::nullopt; | 120 return WTF::nullopt; |
121 } | 121 } |
122 | 122 |
123 // Creates a constraint space for an unpositioned float. | 123 // Creates a constraint space for an unpositioned float. |
124 RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat( | 124 RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat( |
125 const NGUnpositionedFloat& unpositioned_float, | 125 const NGUnpositionedFloat& unpositioned_float, |
126 NGConstraintSpace* parent_space, | 126 NGConstraintSpace* parent_space, |
127 WTF::Optional<LayoutUnit> fragmentation_offset = WTF::nullopt) { | 127 WTF::Optional<LayoutUnit> fragmentation_offset = WTF::nullopt) { |
128 const ComputedStyle& style = unpositioned_float.node->Style(); | 128 const ComputedStyle& style = unpositioned_float.node.Style(); |
129 | 129 |
130 NGConstraintSpaceBuilder builder(parent_space); | 130 NGConstraintSpaceBuilder builder(parent_space); |
131 | 131 |
132 if (fragmentation_offset) { | 132 if (fragmentation_offset) { |
133 builder.SetFragmentainerSpaceAvailable(fragmentation_offset.value()) | 133 builder.SetFragmentainerSpaceAvailable(fragmentation_offset.value()) |
134 .SetFragmentationType(parent_space->BlockFragmentationType()); | 134 .SetFragmentationType(parent_space->BlockFragmentationType()); |
135 } else { | 135 } else { |
136 builder.SetFragmentationType(NGFragmentationType::kFragmentNone); | 136 builder.SetFragmentationType(NGFragmentationType::kFragmentNone); |
137 } | 137 } |
138 | 138 |
139 return builder.SetPercentageResolutionSize(unpositioned_float.percentage_size) | 139 return builder.SetPercentageResolutionSize(unpositioned_float.percentage_size) |
140 .SetAvailableSize(unpositioned_float.available_size) | 140 .SetAvailableSize(unpositioned_float.available_size) |
141 .SetIsNewFormattingContext(true) | 141 .SetIsNewFormattingContext(true) |
142 .SetIsShrinkToFit(true) | 142 .SetIsShrinkToFit(true) |
143 .SetTextDirection(style.Direction()) | 143 .SetTextDirection(style.Direction()) |
144 .ToConstraintSpace(FromPlatformWritingMode(style.GetWritingMode())); | 144 .ToConstraintSpace(FromPlatformWritingMode(style.GetWritingMode())); |
145 } | 145 } |
146 | 146 |
147 } // namespace | 147 } // namespace |
148 | 148 |
149 LayoutUnit ComputeInlineSizeForUnpositionedFloat( | 149 LayoutUnit ComputeInlineSizeForUnpositionedFloat( |
150 NGConstraintSpace* parent_space, | 150 NGConstraintSpace* parent_space, |
151 NGUnpositionedFloat* unpositioned_float) { | 151 NGUnpositionedFloat* unpositioned_float) { |
152 DCHECK(unpositioned_float); | 152 DCHECK(unpositioned_float); |
153 | 153 |
154 const ComputedStyle& style = unpositioned_float->node->Style(); | 154 const ComputedStyle& style = unpositioned_float->node.Style(); |
155 | 155 |
156 bool is_same_writing_mode = FromPlatformWritingMode(style.GetWritingMode()) == | 156 bool is_same_writing_mode = FromPlatformWritingMode(style.GetWritingMode()) == |
157 parent_space->WritingMode(); | 157 parent_space->WritingMode(); |
158 | 158 |
159 // If we've already performed layout on the unpositioned float, just return | 159 // If we've already performed layout on the unpositioned float, just return |
160 // the cached value. | 160 // the cached value. |
161 if (unpositioned_float->fragment) { | 161 if (unpositioned_float->fragment) { |
162 DCHECK(!is_same_writing_mode); | 162 DCHECK(!is_same_writing_mode); |
163 return NGBoxFragment(parent_space->WritingMode(), | 163 return NGBoxFragment(parent_space->WritingMode(), |
164 unpositioned_float->fragment.value().Get()) | 164 unpositioned_float->fragment.value().Get()) |
165 .InlineSize(); | 165 .InlineSize(); |
166 } | 166 } |
167 | 167 |
168 const RefPtr<NGConstraintSpace> space = | 168 const RefPtr<NGConstraintSpace> space = |
169 CreateConstraintSpaceForFloat(*unpositioned_float, parent_space); | 169 CreateConstraintSpaceForFloat(*unpositioned_float, parent_space); |
170 | 170 |
171 // If the float has the same writing mode as the block formatting context we | 171 // If the float has the same writing mode as the block formatting context we |
172 // shouldn't perform a full layout just yet. Our position may determine where | 172 // shouldn't perform a full layout just yet. Our position may determine where |
173 // we fragment. | 173 // we fragment. |
174 if (is_same_writing_mode) { | 174 if (is_same_writing_mode) { |
175 WTF::Optional<MinMaxContentSize> min_max_size; | 175 WTF::Optional<MinMaxContentSize> min_max_size; |
176 if (NeedMinMaxContentSize(*space.Get(), style)) | 176 if (NeedMinMaxContentSize(*space.Get(), style)) |
177 min_max_size = unpositioned_float->node->ComputeMinMaxContentSize(); | 177 min_max_size = unpositioned_float->node.ComputeMinMaxContentSize(); |
178 return ComputeInlineSizeForFragment(*space.Get(), style, min_max_size); | 178 return ComputeInlineSizeForFragment(*space.Get(), style, min_max_size); |
179 } | 179 } |
180 | 180 |
181 // If we are performing layout on a float to determine its inline size it | 181 // If we are performing layout on a float to determine its inline size it |
182 // should never have fragmented. | 182 // should never have fragmented. |
183 DCHECK(!unpositioned_float->token); | 183 DCHECK(!unpositioned_float->token); |
184 | 184 |
185 // A float which has a different writing mode can't fragment, and we | 185 // A float which has a different writing mode can't fragment, and we |
186 // (probably) need to perform a full layout in order to correctly determine | 186 // (probably) need to perform a full layout in order to correctly determine |
187 // its inline size. We are able to cache this result on the | 187 // its inline size. We are able to cache this result on the |
188 // unpositioned_float at this stage. | 188 // unpositioned_float at this stage. |
189 RefPtr<NGLayoutResult> layout_result = | 189 RefPtr<NGLayoutResult> layout_result = |
190 unpositioned_float->node->Layout(space.Get()); | 190 unpositioned_float->node.Layout(space.Get()); |
191 | 191 |
192 RefPtr<NGPhysicalBoxFragment> fragment = | 192 RefPtr<NGPhysicalBoxFragment> fragment = |
193 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()); | 193 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()); |
194 unpositioned_float->fragment = fragment; | 194 unpositioned_float->fragment = fragment; |
195 | 195 |
196 DCHECK(fragment->BreakToken()->IsFinished()); | 196 DCHECK(fragment->BreakToken()->IsFinished()); |
197 | 197 |
198 return NGBoxFragment(parent_space->WritingMode(), fragment.Get()) | 198 return NGBoxFragment(parent_space->WritingMode(), fragment.Get()) |
199 .InlineSize(); | 199 .InlineSize(); |
200 } | 200 } |
201 | 201 |
202 NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float, | 202 NGPositionedFloat PositionFloat(NGUnpositionedFloat* unpositioned_float, |
203 NGConstraintSpace* new_parent_space) { | 203 NGConstraintSpace* new_parent_space) { |
204 DCHECK(unpositioned_float); | 204 DCHECK(unpositioned_float); |
205 LayoutUnit inline_size = ComputeInlineSizeForUnpositionedFloat( | 205 LayoutUnit inline_size = ComputeInlineSizeForUnpositionedFloat( |
206 new_parent_space, unpositioned_float); | 206 new_parent_space, unpositioned_float); |
207 | 207 |
208 // Find a layout opportunity that will fit our float. | 208 // Find a layout opportunity that will fit our float. |
209 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat( | 209 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat( |
210 *new_parent_space, *unpositioned_float, inline_size); | 210 *new_parent_space, *unpositioned_float, inline_size); |
211 | 211 |
212 #if DCHECK_IS_ON() | 212 #if DCHECK_IS_ON() |
213 bool is_same_writing_mode = | 213 bool is_same_writing_mode = |
214 FromPlatformWritingMode( | 214 FromPlatformWritingMode( |
215 unpositioned_float->node->Style().GetWritingMode()) == | 215 unpositioned_float->node.Style().GetWritingMode()) == |
216 new_parent_space->WritingMode(); | 216 new_parent_space->WritingMode(); |
217 #endif | 217 #endif |
218 | 218 |
219 RefPtr<NGPhysicalBoxFragment> physical_fragment; | 219 RefPtr<NGPhysicalBoxFragment> physical_fragment; |
220 // We should only have a fragment if its writing mode is different, i.e. it | 220 // We should only have a fragment if its writing mode is different, i.e. it |
221 // can't fragment. | 221 // can't fragment. |
222 if (unpositioned_float->fragment) { | 222 if (unpositioned_float->fragment) { |
223 #if DCHECK_IS_ON() | 223 #if DCHECK_IS_ON() |
224 DCHECK(!is_same_writing_mode); | 224 DCHECK(!is_same_writing_mode); |
225 #endif | 225 #endif |
226 physical_fragment = unpositioned_float->fragment.value(); | 226 physical_fragment = unpositioned_float->fragment.value(); |
227 } else { | 227 } else { |
228 #if DCHECK_IS_ON() | 228 #if DCHECK_IS_ON() |
229 DCHECK(is_same_writing_mode); | 229 DCHECK(is_same_writing_mode); |
230 #endif | 230 #endif |
231 WTF::Optional<LayoutUnit> fragmentation_offset = | 231 WTF::Optional<LayoutUnit> fragmentation_offset = |
232 CalculateFragmentationOffset(*unpositioned_float, *new_parent_space); | 232 CalculateFragmentationOffset(*unpositioned_float, *new_parent_space); |
233 | 233 |
234 RefPtr<NGConstraintSpace> space = CreateConstraintSpaceForFloat( | 234 RefPtr<NGConstraintSpace> space = CreateConstraintSpaceForFloat( |
235 *unpositioned_float, new_parent_space, fragmentation_offset); | 235 *unpositioned_float, new_parent_space, fragmentation_offset); |
236 RefPtr<NGLayoutResult> layout_result = unpositioned_float->node->Layout( | 236 RefPtr<NGLayoutResult> layout_result = unpositioned_float->node.Layout( |
237 space.Get(), unpositioned_float->token.Get()); | 237 space.Get(), unpositioned_float->token.Get()); |
238 physical_fragment = | 238 physical_fragment = |
239 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()); | 239 ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()); |
240 } | 240 } |
241 | 241 |
242 NGBoxFragment float_fragment(new_parent_space->WritingMode(), | 242 NGBoxFragment float_fragment(new_parent_space->WritingMode(), |
243 physical_fragment.Get()); | 243 physical_fragment.Get()); |
244 | 244 |
245 // TODO(glebl): This should check for infinite opportunity instead. | 245 // TODO(glebl): This should check for infinite opportunity instead. |
246 if (opportunity.IsEmpty()) { | 246 if (opportunity.IsEmpty()) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 unpositioned_float->origin_offset.block_offset = origin_block_offset; | 290 unpositioned_float->origin_offset.block_offset = origin_block_offset; |
291 unpositioned_float->from_offset.block_offset = from_block_offset; | 291 unpositioned_float->from_offset.block_offset = from_block_offset; |
292 unpositioned_float->parent_bfc_block_offset = parent_bfc_offset; | 292 unpositioned_float->parent_bfc_block_offset = parent_bfc_offset; |
293 positioned_floats.push_back(PositionFloat(unpositioned_float.Get(), space)); | 293 positioned_floats.push_back(PositionFloat(unpositioned_float.Get(), space)); |
294 } | 294 } |
295 | 295 |
296 return positioned_floats; | 296 return positioned_floats; |
297 } | 297 } |
298 | 298 |
299 } // namespace blink | 299 } // namespace blink |
OLD | NEW |