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

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

Issue 2389823003: Fix incorrectly calculated content_size for fragments that create new FC (Closed)
Patch Set: keep the Collapsing margins logic consolidated in one place Created 4 years, 2 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_block_layout_algorithm.h" 5 #include "core/layout/ng/ng_block_layout_algorithm.h"
6 6
7 #include "core/layout/ng/ng_constraint_space.h" 7 #include "core/layout/ng/ng_constraint_space.h"
8 #include "core/layout/ng/ng_fragment_builder.h" 8 #include "core/layout/ng/ng_fragment_builder.h"
9 #include "core/layout/ng/ng_fragment.h" 9 #include "core/layout/ng/ng_fragment.h"
10 #include "core/layout/ng/ng_length_utils.h" 10 #include "core/layout/ng/ng_length_utils.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 case kStateChildLayout: { 74 case kStateChildLayout: {
75 if (current_child_) { 75 if (current_child_) {
76 NGFragment* fragment; 76 NGFragment* fragment;
77 if (!current_child_->Layout(constraint_space_for_children_, &fragment)) 77 if (!current_child_->Layout(constraint_space_for_children_, &fragment))
78 return false; 78 return false;
79 NGBoxStrut child_margins = computeMargins( 79 NGBoxStrut child_margins = computeMargins(
80 *constraint_space_for_children_, *current_child_->Style(), 80 *constraint_space_for_children_, *current_child_->Style(),
81 constraint_space_for_children_->WritingMode(), 81 constraint_space_for_children_->WritingMode(),
82 constraint_space_for_children_->Direction()); 82 constraint_space_for_children_->Direction());
83 83
84 LayoutUnit margin_block_start = 84 const NGBoxStrut margins =
85 CollapseMargins(*constraint_space, child_margins, *fragment); 85 CollapseMargins(*constraint_space, child_margins, *fragment);
86 86
87 // TODO(layout-ng): Support auto margins 87 // TODO(layout-ng): Support auto margins
88 builder_->AddChild(fragment, 88 builder_->AddChild(
89 NGLogicalOffset(border_and_padding_.inline_start + 89 fragment, NGLogicalOffset(border_and_padding_.inline_start +
90 child_margins.inline_start, 90 child_margins.inline_start,
91 content_size_ + margin_block_start)); 91 content_size_ + margins.block_start));
92 92
93 content_size_ += fragment->BlockSize() + margin_block_start; 93 content_size_ += fragment->BlockSize() + margins.BlockSum();
94 max_inline_size_ = 94 max_inline_size_ =
95 std::max(max_inline_size_, fragment->InlineSize() + 95 std::max(max_inline_size_, fragment->InlineSize() +
96 child_margins.InlineSum() + 96 child_margins.InlineSum() +
97 border_and_padding_.InlineSum()); 97 border_and_padding_.InlineSum());
98 current_child_ = current_child_->NextSibling(); 98 current_child_ = current_child_->NextSibling();
99 if (current_child_) 99 if (current_child_)
100 return false; 100 return false;
101 } 101 }
102 state_ = kStateFinalize; 102 state_ = kStateFinalize;
103 return false; 103 return false;
104 } 104 }
105 case kStateFinalize: { 105 case kStateFinalize: {
106 content_size_ += border_and_padding_.block_end; 106 content_size_ += border_and_padding_.block_end;
107
107 // Recompute the block-axis size now that we know our content size. 108 // Recompute the block-axis size now that we know our content size.
108 LayoutUnit block_size = computeBlockSizeForFragment( 109 LayoutUnit block_size = computeBlockSizeForFragment(
109 *constraint_space, *style_, content_size_); 110 *constraint_space, *style_, content_size_);
110 111
111 builder_->SetBlockSize(block_size) 112 builder_->SetBlockSize(block_size)
112 .SetInlineOverflow(max_inline_size_) 113 .SetInlineOverflow(max_inline_size_)
113 .SetBlockOverflow(content_size_); 114 .SetBlockOverflow(content_size_);
114 *out = builder_->ToFragment(); 115 *out = builder_->ToFragment();
115 state_ = kStateInit; 116 state_ = kStateInit;
116 return true; 117 return true;
117 } 118 }
118 }; 119 };
119 NOTREACHED(); 120 NOTREACHED();
120 *out = nullptr; 121 *out = nullptr;
121 return true; 122 return true;
122 } 123 }
123 124
124 LayoutUnit NGBlockLayoutAlgorithm::CollapseMargins( 125 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins(
125 const NGConstraintSpace& space, 126 const NGConstraintSpace& space,
126 const NGBoxStrut& margins, 127 const NGBoxStrut& margins,
127 const NGFragment& fragment) { 128 const NGFragment& fragment) {
128 // Zero-height boxes are ignored and do not participate in margin collapsing. 129 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() &&
129 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty(); 130 fragment.MarginStrut().IsEmpty();
130 if (is_zero_height_box) 131 // Create the current child's margin strut from its children's margin strut or
131 return LayoutUnit(); 132 // use margin strut from the the last non-empty child.
132 133 NGMarginStrut curr_margin_strut =
133 // Create the current child's margin strut from its children's margin strut. 134 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut();
134 NGMarginStrut curr_margin_strut = fragment.MarginStrut();
135 135
136 // Calculate borders and padding for the current child. 136 // Calculate borders and padding for the current child.
137 NGBoxStrut border_and_padding = 137 NGBoxStrut border_and_padding =
138 computeBorders(*current_child_->Style()) + 138 computeBorders(*current_child_->Style()) +
139 computePadding(space, *current_child_->Style()); 139 computePadding(space, *current_child_->Style());
140 140
141 // Collapse BLOCK-START margins if there is no padding or border between 141 // Collapse BLOCK-START margins if there is no padding or border between
142 // parent (current child) and its first in-flow child. 142 // parent (current child) and its first in-flow child.
143 if (border_and_padding.block_start) { 143 if (border_and_padding.block_start) {
144 curr_margin_strut.SetMarginBlockStart(margins.block_start); 144 curr_margin_strut.SetMarginBlockStart(margins.block_start);
145 } else { 145 } else {
146 curr_margin_strut.AppendMarginBlockStart(margins.block_start); 146 curr_margin_strut.AppendMarginBlockStart(margins.block_start);
147 } 147 }
148 148
149 // Collapse BLOCK-END margins if 149 // Collapse BLOCK-END margins if
150 // 1) there is no padding or border between parent (current child) and its 150 // 1) there is no padding or border between parent (current child) and its
151 // first/last in-flow child 151 // first/last in-flow child
152 // 2) parent's logical height is auto. 152 // 2) parent's logical height is auto.
153 if (current_child_->Style()->logicalHeight().isAuto() && 153 if (current_child_->Style()->logicalHeight().isAuto() &&
154 !border_and_padding.block_end) { 154 !border_and_padding.block_end) {
155 curr_margin_strut.AppendMarginBlockEnd(margins.block_end); 155 curr_margin_strut.AppendMarginBlockEnd(margins.block_end);
156 } else { 156 } else {
157 curr_margin_strut.SetMarginBlockEnd(margins.block_end); 157 curr_margin_strut.SetMarginBlockEnd(margins.block_end);
158 } 158 }
159 159
160 NGBoxStrut result_margins;
161 // Margins of the newly established formatting context do not participate
162 // in Collapsing Margins.
163 bool is_last_child = !current_child_->NextSibling();
164 if (is_last_child && space.IsNewFormattingContext()) {
165 result_margins.block_end = curr_margin_strut.BlockEndSum();
166 builder_->ClearMarginStrut();
ikilpatrick 2016/10/04 16:21:35 isn't this immediately going to be set at UpdateMa
167 }
168
169 // Zero-height boxes are ignored and do not participate in margin collapsing.
170 if (is_zero_height_box)
171 return result_margins;
172
160 // Compute the margin block start for 173 // Compute the margin block start for
161 // 1) adjoining blocks 174 // 1) adjoining blocks
162 // 2) 1st block in the newly established formatting context. 175 // 2) 1st block in the newly established formatting context.
163 LayoutUnit margin_block_start;
164 if (is_fragment_margin_strut_block_start_updated_ || 176 if (is_fragment_margin_strut_block_start_updated_ ||
165 space.IsNewFormattingContext()) { 177 space.IsNewFormattingContext()) {
166 margin_block_start = ComputeCollapsedMarginBlockStart( 178 result_margins.block_start = ComputeCollapsedMarginBlockStart(
167 prev_child_margin_strut_, curr_margin_strut); 179 prev_child_margin_strut_, curr_margin_strut);
168 } 180 }
169 181
170 // Update the parent fragment's margin strut 182 // Update the parent fragment's margin strut
171 UpdateMarginStrut(curr_margin_strut); 183 UpdateMarginStrut(curr_margin_strut);
172 184
173 prev_child_margin_strut_ = curr_margin_strut; 185 prev_child_margin_strut_ = curr_margin_strut;
174 return margin_block_start; 186 return result_margins;
175 } 187 }
176 188
177 void NGBlockLayoutAlgorithm::UpdateMarginStrut(const NGMarginStrut& from) { 189 void NGBlockLayoutAlgorithm::UpdateMarginStrut(const NGMarginStrut& from) {
178 if (!is_fragment_margin_strut_block_start_updated_) { 190 if (!is_fragment_margin_strut_block_start_updated_) {
179 builder_->SetMarginStrutBlockStart(from); 191 builder_->SetMarginStrutBlockStart(from);
180 is_fragment_margin_strut_block_start_updated_ = true; 192 is_fragment_margin_strut_block_start_updated_ = true;
181 } 193 }
182 builder_->SetMarginStrutBlockEnd(from); 194 builder_->SetMarginStrutBlockEnd(from);
183 } 195 }
184 196
185 } // namespace blink 197 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698