Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 |
| OLD | NEW |