Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_floats_utils.cc

Issue 2790283003: Reset constraint space's BFC offset if block creates a new FC (Closed)
Patch Set: git rebase-update Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 8
9 namespace blink { 9 namespace blink {
10 namespace { 10 namespace {
(...skipping 18 matching lines...) Expand all
29 } 29 }
30 30
31 // Finds a layout opportunity for the fragment. 31 // Finds a layout opportunity for the fragment.
32 // It iterates over all layout opportunities in the constraint space and returns 32 // 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 33 // the first layout opportunity that is wider than the fragment or returns the
34 // last one which is always the widest. 34 // last one which is always the widest.
35 // 35 //
36 // @param space Constraint space that is used to find layout opportunity for 36 // @param space Constraint space that is used to find layout opportunity for
37 // the fragment. 37 // the fragment.
38 // @param fragment Fragment that needs to be placed. 38 // @param fragment Fragment that needs to be placed.
39 // @param origin_point {@code space}'s offset relative to the space that 39 // @param floating_object Floating object for which we need to find a layout
40 // establishes a new formatting context that we're currently 40 // opportunity.
41 // in and where all our exclusions reside.
42 // @param margins Margins of the fragment.
43 // @param available_size Available size used by the layout opportunity iterator.
44 // @return Layout opportunity for the fragment. 41 // @return Layout opportunity for the fragment.
45 const NGLayoutOpportunity FindLayoutOpportunityForFragment( 42 const NGLayoutOpportunity FindLayoutOpportunityForFragment(
46 const NGConstraintSpace* space, 43 const NGConstraintSpace* space,
47 const NGFragment& fragment, 44 const NGFragment& fragment,
48 const NGLogicalOffset& origin_point, 45 const NGFloatingObject* floating_object) {
49 const NGBoxStrut& margins,
50 const NGLogicalSize& available_size) {
51 NGLogicalOffset adjusted_origin_point = 46 NGLogicalOffset adjusted_origin_point =
52 AdjustToTopEdgeAlignmentRule(*space, origin_point); 47 AdjustToTopEdgeAlignmentRule(*space, floating_object->origin_offset);
53 48
54 NGLayoutOpportunityIterator opportunity_iter(space, available_size, 49 NGLayoutOpportunityIterator opportunity_iter(
55 adjusted_origin_point); 50 space, floating_object->available_size, adjusted_origin_point);
56 NGLayoutOpportunity opportunity; 51 NGLayoutOpportunity opportunity;
57 NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next(); 52 NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next();
58 53
54 NGBoxStrut margins = floating_object->margins;
59 while (!opportunity_candidate.IsEmpty()) { 55 while (!opportunity_candidate.IsEmpty()) {
60 opportunity = opportunity_candidate; 56 opportunity = opportunity_candidate;
61 // Checking opportunity's block size is not necessary as a float cannot be 57 // Checking opportunity's block size is not necessary as a float cannot be
62 // positioned on top of another float inside of the same constraint space. 58 // positioned on top of another float inside of the same constraint space.
63 auto fragment_inline_size = fragment.InlineSize() + margins.InlineSum(); 59 auto fragment_inline_size = fragment.InlineSize() + margins.InlineSum();
64 if (opportunity.size.inline_size >= fragment_inline_size) 60 if (opportunity.size.inline_size >= fragment_inline_size)
65 break; 61 break;
66 62
67 opportunity_candidate = opportunity_iter.Next(); 63 opportunity_candidate = opportunity_iter.Next();
68 } 64 }
69 return opportunity; 65 return opportunity;
70 } 66 }
71 67
72 // Calculates the logical offset for opportunity. 68 // Calculates the logical offset for opportunity.
73 NGLogicalOffset CalculateLogicalOffsetForOpportunity( 69 NGLogicalOffset CalculateLogicalOffsetForOpportunity(
74 const NGLayoutOpportunity& opportunity, 70 const NGLayoutOpportunity& opportunity,
75 const LayoutUnit float_offset, 71 const LayoutUnit float_offset,
76 const NGLogicalOffset& from_offset, 72 const NGFloatingObject* floating_object) {
77 NGFloatingObject* floating_object) {
78 DCHECK(floating_object); 73 DCHECK(floating_object);
79 auto margins = floating_object->margins; 74 auto margins = floating_object->margins;
80 // Adjust to child's margin. 75 // Adjust to child's margin.
81 LayoutUnit inline_offset = margins.inline_start; 76 NGLogicalOffset result = margins.InlineBlockStartOffset();
82 LayoutUnit block_offset = margins.block_start;
83 77
84 // Offset from the opportunity's block/inline start. 78 // Offset from the opportunity's block/inline start.
85 inline_offset += opportunity.offset.inline_offset; 79 result += opportunity.offset;
86 block_offset += opportunity.offset.block_offset;
87 80
88 // Adjust to float: right offset if needed. 81 // Adjust to float: right offset if needed.
89 inline_offset += float_offset; 82 result.inline_offset += float_offset;
90 83
91 block_offset -= from_offset.block_offset; 84 result -= floating_object->from_offset;
92 inline_offset -= from_offset.inline_offset; 85 return result;
93
94 return NGLogicalOffset(inline_offset, block_offset);
95 } 86 }
96 87
97 // Creates an exclusion from the fragment that will be placed in the provided 88 // Creates an exclusion from the fragment that will be placed in the provided
98 // layout opportunity. 89 // layout opportunity.
99 NGExclusion CreateExclusion(const NGFragment& fragment, 90 NGExclusion CreateExclusion(const NGFragment& fragment,
100 const NGLayoutOpportunity& opportunity, 91 const NGLayoutOpportunity& opportunity,
101 const LayoutUnit float_offset, 92 const LayoutUnit float_offset,
102 const NGBoxStrut& margins, 93 const NGBoxStrut& margins,
103 NGExclusion::Type exclusion_type) { 94 NGExclusion::Type exclusion_type) {
104 NGExclusion exclusion; 95 NGExclusion exclusion;
105 exclusion.type = exclusion_type; 96 exclusion.type = exclusion_type;
106 NGLogicalRect& rect = exclusion.rect; 97 NGLogicalRect& rect = exclusion.rect;
107 rect.offset = opportunity.offset; 98 rect.offset = opportunity.offset;
108 rect.offset.inline_offset += float_offset; 99 rect.offset.inline_offset += float_offset;
109 100
110 rect.size.inline_size = fragment.InlineSize() + margins.InlineSum(); 101 rect.size.inline_size = fragment.InlineSize() + margins.InlineSum();
111 rect.size.block_size = fragment.BlockSize() + margins.BlockSum(); 102 rect.size.block_size = fragment.BlockSize() + margins.BlockSum();
112 return exclusion; 103 return exclusion;
113 } 104 }
114 105
115 // Updates the Floating Object's left offset from the provided parent_space 106 // Updates the Floating Object's left offset from the provided parent_space
116 // and {@code floating_object}'s space and margins. 107 // and {@code floating_object}'s space and margins.
117 void UpdateFloatingObjectLeftOffset(const NGConstraintSpace& new_parent_space, 108 void UpdateFloatingObjectLeftOffset(const NGConstraintSpace& new_parent_space,
118 const NGLogicalOffset& float_logical_offset, 109 const NGLogicalOffset& float_logical_offset,
119 NGFloatingObject* floating_object) { 110 NGFloatingObject* floating_object) {
120 DCHECK(floating_object); 111 DCHECK(floating_object);
121 // TODO(glebl): We should use physical offset here. 112 // TODO(glebl): We should use physical offset here.
122 floating_object->left_offset = 113 floating_object->left_offset = floating_object->from_offset.inline_offset -
123 floating_object->original_parent_space->BfcOffset().inline_offset - 114 new_parent_space.BfcOffset().inline_offset +
124 new_parent_space.BfcOffset().inline_offset + 115 float_logical_offset.inline_offset;
125 float_logical_offset.inline_offset;
126 } 116 }
127 } // namespace 117 } // namespace
128 118
129 // Calculates the relative position from {@code from_offset} of the 119 NGLogicalOffset PositionFloat(NGFloatingObject* floating_object,
130 // floating object that is requested to be positioned from {@code origin_point}.
131 NGLogicalOffset PositionFloat(const NGLogicalOffset& origin_point,
132 const NGLogicalOffset& from_offset,
133 NGFloatingObject* floating_object,
134 NGConstraintSpace* new_parent_space) { 120 NGConstraintSpace* new_parent_space) {
135 DCHECK(floating_object); 121 DCHECK(floating_object);
136 const auto* float_space = floating_object->space.get();
137 DCHECK(floating_object->fragment) << "Fragment cannot be null here"; 122 DCHECK(floating_object->fragment) << "Fragment cannot be null here";
138 123
139 // TODO(ikilpatrick): The writing mode switching here looks wrong. 124 // TODO(ikilpatrick): The writing mode switching here looks wrong.
140 NGBoxFragment float_fragment( 125 NGBoxFragment float_fragment(
141 float_space->WritingMode(), 126 floating_object->writing_mode,
142 toNGPhysicalBoxFragment(floating_object->fragment.get())); 127 toNGPhysicalBoxFragment(floating_object->fragment.get()));
143 128
144 // Find a layout opportunity that will fit our float. 129 // Find a layout opportunity that will fit our float.
145 const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment( 130 const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment(
146 new_parent_space, float_fragment, origin_point, floating_object->margins, 131 new_parent_space, float_fragment, floating_object);
147 floating_object->available_size);
148 DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be"; 132 DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be";
149 133
150 // Calculate the float offset if needed. 134 // Calculate the float offset if needed.
151 LayoutUnit float_offset; 135 LayoutUnit float_offset;
152 if (floating_object->exclusion_type == NGExclusion::kFloatRight) { 136 if (floating_object->exclusion_type == NGExclusion::kFloatRight) {
153 LayoutUnit float_margin_box_inline_size = 137 LayoutUnit float_margin_box_inline_size =
154 float_fragment.InlineSize() + floating_object->margins.InlineSum(); 138 float_fragment.InlineSize() + floating_object->margins.InlineSum();
155 float_offset = opportunity.size.inline_size - float_margin_box_inline_size; 139 float_offset = opportunity.size.inline_size - float_margin_box_inline_size;
156 } 140 }
157 141
158 // Add the float as an exclusion. 142 // Add the float as an exclusion.
159 const NGExclusion exclusion = CreateExclusion( 143 const NGExclusion exclusion = CreateExclusion(
160 float_fragment, opportunity, float_offset, floating_object->margins, 144 float_fragment, opportunity, float_offset, floating_object->margins,
161 floating_object->exclusion_type); 145 floating_object->exclusion_type);
162 new_parent_space->AddExclusion(exclusion); 146 new_parent_space->AddExclusion(exclusion);
163 147
164 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity( 148 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity(
165 opportunity, float_offset, from_offset, floating_object); 149 opportunity, float_offset, floating_object);
166 UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset, 150 UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset,
167 floating_object); 151 floating_object);
168 return logical_offset; 152 return logical_offset;
169 } 153 }
154
155 void PositionPendingFloats(const LayoutUnit& origin_block_offset,
156 NGConstraintSpace* space,
157 NGFragmentBuilder* builder) {
158 DCHECK(builder) << "Builder cannot be null here";
159 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here";
160 LayoutUnit bfc_block_offset = builder->BfcOffset().value().block_offset;
161
162 for (auto& floating_object : builder->UnpositionedFloats()) {
163 floating_object->origin_offset.block_offset = origin_block_offset;
164 floating_object->from_offset.block_offset = bfc_block_offset;
165
166 NGLogicalOffset offset = PositionFloat(floating_object.get(), space);
167 builder->AddFloatingObject(floating_object, offset);
168 }
169 builder->MutableUnpositionedFloats().clear();
170 }
171
170 } // namespace blink 172 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698