| 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_length_utils.h" | 5 #include "core/layout/ng/ng_length_utils.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.h" | 8 #include "core/layout/ng/ng_fragment.h" |
| 9 #include "core/style/ComputedStyle.h" | 9 #include "core/style/ComputedStyle.h" |
| 10 #include "platform/LayoutUnit.h" | 10 #include "platform/LayoutUnit.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 logical_dim = {is_ltr ? physical_dim.left : physical_dim.right, | 49 logical_dim = {is_ltr ? physical_dim.left : physical_dim.right, |
| 50 is_ltr ? physical_dim.right : physical_dim.left, | 50 is_ltr ? physical_dim.right : physical_dim.left, |
| 51 physical_dim.top, physical_dim.bottom}; | 51 physical_dim.top, physical_dim.bottom}; |
| 52 break; | 52 break; |
| 53 } | 53 } |
| 54 return logical_dim; | 54 return logical_dim; |
| 55 } | 55 } |
| 56 | 56 |
| 57 } // namespace | 57 } // namespace |
| 58 | 58 |
| 59 LayoutUnit resolveInlineLength(const NGConstraintSpace& constraintSpace, | 59 LayoutUnit ResolveInlineLength(const NGConstraintSpace& constraintSpace, |
| 60 const ComputedStyle& style, | 60 const ComputedStyle& style, |
| 61 const Length& length, | 61 const Length& length, |
| 62 LengthResolveType type) { | 62 LengthResolveType type) { |
| 63 // TODO(layout-ng): Handle min/max/fit-content | 63 // TODO(layout-ng): Handle min/max/fit-content |
| 64 DCHECK(!length.isMaxSizeNone()); | 64 DCHECK(!length.isMaxSizeNone()); |
| 65 DCHECK_GE(constraintSpace.ContainerSize().inline_size, LayoutUnit()); | 65 DCHECK_GE(constraintSpace.ContainerSize().inline_size, LayoutUnit()); |
| 66 | 66 |
| 67 if (type == LengthResolveType::MinSize && length.isAuto()) | 67 if (type == LengthResolveType::MinSize && length.isAuto()) |
| 68 return LayoutUnit(); | 68 return LayoutUnit(); |
| 69 | 69 |
| 70 if (type == LengthResolveType::MarginBorderPaddingSize && length.isAuto()) | 70 if (type == LengthResolveType::MarginBorderPaddingSize && length.isAuto()) |
| 71 return LayoutUnit(); | 71 return LayoutUnit(); |
| 72 | 72 |
| 73 // We don't need this when we're resolving margin/border/padding; skip | 73 // We don't need this when we're resolving margin/border/padding; skip |
| 74 // computing it as an optimization and to simplify the code below. | 74 // computing it as an optimization and to simplify the code below. |
| 75 NGBoxStrut border_and_padding; | 75 NGBoxStrut border_and_padding; |
| 76 if (type != LengthResolveType::MarginBorderPaddingSize) { | 76 if (type != LengthResolveType::MarginBorderPaddingSize) { |
| 77 border_and_padding = | 77 border_and_padding = |
| 78 computeBorders(style) + computePadding(constraintSpace, style); | 78 ComputeBorders(style) + ComputePadding(constraintSpace, style); |
| 79 } | 79 } |
| 80 LayoutUnit container_size = constraintSpace.ContainerSize().inline_size; | 80 LayoutUnit container_size = constraintSpace.ContainerSize().inline_size; |
| 81 switch (length.type()) { | 81 switch (length.type()) { |
| 82 case Auto: | 82 case Auto: |
| 83 case FillAvailable: { | 83 case FillAvailable: { |
| 84 NGBoxStrut margins = | 84 NGBoxStrut margins = |
| 85 computeMargins(constraintSpace, style, | 85 ComputeMargins(constraintSpace, style, |
| 86 FromPlatformWritingMode(style.getWritingMode()), | 86 FromPlatformWritingMode(style.getWritingMode()), |
| 87 FromPlatformDirection(style.direction())); | 87 FromPlatformDirection(style.direction())); |
| 88 return std::max(border_and_padding.InlineSum(), | 88 return std::max(border_and_padding.InlineSum(), |
| 89 container_size - margins.InlineSum()); | 89 container_size - margins.InlineSum()); |
| 90 } | 90 } |
| 91 case Percent: | 91 case Percent: |
| 92 case Fixed: | 92 case Fixed: |
| 93 case Calculated: { | 93 case Calculated: { |
| 94 LayoutUnit value = valueForLength(length, container_size); | 94 LayoutUnit value = valueForLength(length, container_size); |
| 95 if (style.boxSizing() == BoxSizingContentBox) { | 95 if (style.boxSizing() == BoxSizingContentBox) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 108 case DeviceHeight: | 108 case DeviceHeight: |
| 109 case ExtendToZoom: | 109 case ExtendToZoom: |
| 110 NOTREACHED() << "These should only be used for viewport definitions"; | 110 NOTREACHED() << "These should only be used for viewport definitions"; |
| 111 case MaxSizeNone: | 111 case MaxSizeNone: |
| 112 default: | 112 default: |
| 113 NOTREACHED(); | 113 NOTREACHED(); |
| 114 return border_and_padding.InlineSum(); | 114 return border_and_padding.InlineSum(); |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 | 117 |
| 118 LayoutUnit resolveBlockLength(const NGConstraintSpace& constraintSpace, | 118 LayoutUnit ResolveBlockLength(const NGConstraintSpace& constraintSpace, |
| 119 const ComputedStyle& style, | 119 const ComputedStyle& style, |
| 120 const Length& length, | 120 const Length& length, |
| 121 LayoutUnit contentSize, | 121 LayoutUnit contentSize, |
| 122 LengthResolveType type) { | 122 LengthResolveType type) { |
| 123 DCHECK(!length.isMaxSizeNone()); | 123 DCHECK(!length.isMaxSizeNone()); |
| 124 DCHECK(type != LengthResolveType::MarginBorderPaddingSize); | 124 DCHECK(type != LengthResolveType::MarginBorderPaddingSize); |
| 125 | 125 |
| 126 if (type == LengthResolveType::MinSize && length.isAuto()) | 126 if (type == LengthResolveType::MinSize && length.isAuto()) |
| 127 return LayoutUnit(); | 127 return LayoutUnit(); |
| 128 | 128 |
| 129 // Make sure that indefinite percentages resolve to NGSizeIndefinite, not to | 129 // Make sure that indefinite percentages resolve to NGSizeIndefinite, not to |
| 130 // a random negative number. | 130 // a random negative number. |
| 131 if (length.isPercentOrCalc() && | 131 if (length.isPercentOrCalc() && |
| 132 constraintSpace.ContainerSize().block_size == NGSizeIndefinite) | 132 constraintSpace.ContainerSize().block_size == NGSizeIndefinite) |
| 133 return contentSize; | 133 return contentSize; |
| 134 | 134 |
| 135 // We don't need this when we're resolving margin/border/padding; skip | 135 // We don't need this when we're resolving margin/border/padding; skip |
| 136 // computing it as an optimization and to simplify the code below. | 136 // computing it as an optimization and to simplify the code below. |
| 137 NGBoxStrut border_and_padding; | 137 NGBoxStrut border_and_padding; |
| 138 if (type != LengthResolveType::MarginBorderPaddingSize) { | 138 if (type != LengthResolveType::MarginBorderPaddingSize) { |
| 139 border_and_padding = | 139 border_and_padding = |
| 140 computeBorders(style) + computePadding(constraintSpace, style); | 140 ComputeBorders(style) + ComputePadding(constraintSpace, style); |
| 141 } | 141 } |
| 142 LayoutUnit container_size = constraintSpace.ContainerSize().block_size; | 142 LayoutUnit container_size = constraintSpace.ContainerSize().block_size; |
| 143 switch (length.type()) { | 143 switch (length.type()) { |
| 144 case FillAvailable: { | 144 case FillAvailable: { |
| 145 NGBoxStrut margins = | 145 NGBoxStrut margins = |
| 146 computeMargins(constraintSpace, style, | 146 ComputeMargins(constraintSpace, style, |
| 147 FromPlatformWritingMode(style.getWritingMode()), | 147 FromPlatformWritingMode(style.getWritingMode()), |
| 148 FromPlatformDirection(style.direction())); | 148 FromPlatformDirection(style.direction())); |
| 149 return std::max(border_and_padding.BlockSum(), | 149 return std::max(border_and_padding.BlockSum(), |
| 150 container_size - margins.BlockSum()); | 150 container_size - margins.BlockSum()); |
| 151 } | 151 } |
| 152 case Percent: | 152 case Percent: |
| 153 case Fixed: | 153 case Fixed: |
| 154 case Calculated: { | 154 case Calculated: { |
| 155 LayoutUnit value = valueForLength(length, container_size); | 155 LayoutUnit value = valueForLength(length, container_size); |
| 156 if (style.boxSizing() == BoxSizingContentBox) { | 156 if (style.boxSizing() == BoxSizingContentBox) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 173 case DeviceHeight: | 173 case DeviceHeight: |
| 174 case ExtendToZoom: | 174 case ExtendToZoom: |
| 175 NOTREACHED() << "These should only be used for viewport definitions"; | 175 NOTREACHED() << "These should only be used for viewport definitions"; |
| 176 case MaxSizeNone: | 176 case MaxSizeNone: |
| 177 default: | 177 default: |
| 178 NOTREACHED(); | 178 NOTREACHED(); |
| 179 return border_and_padding.BlockSum(); | 179 return border_and_padding.BlockSum(); |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 LayoutUnit computeInlineSizeForFragment( | 183 LayoutUnit ComputeInlineSizeForFragment( |
| 184 const NGConstraintSpace& constraintSpace, | 184 const NGConstraintSpace& constraintSpace, |
| 185 const ComputedStyle& style) { | 185 const ComputedStyle& style) { |
| 186 if (constraintSpace.FixedInlineSize()) | 186 if (constraintSpace.FixedInlineSize()) |
| 187 return constraintSpace.ContainerSize().inline_size; | 187 return constraintSpace.ContainerSize().inline_size; |
| 188 | 188 |
| 189 LayoutUnit extent = | 189 LayoutUnit extent = |
| 190 resolveInlineLength(constraintSpace, style, style.logicalWidth(), | 190 ResolveInlineLength(constraintSpace, style, style.logicalWidth(), |
| 191 LengthResolveType::ContentSize); | 191 LengthResolveType::ContentSize); |
| 192 | 192 |
| 193 Length maxLength = style.logicalMaxWidth(); | 193 Length maxLength = style.logicalMaxWidth(); |
| 194 if (!maxLength.isMaxSizeNone()) { | 194 if (!maxLength.isMaxSizeNone()) { |
| 195 LayoutUnit max = resolveInlineLength(constraintSpace, style, maxLength, | 195 LayoutUnit max = ResolveInlineLength(constraintSpace, style, maxLength, |
| 196 LengthResolveType::MaxSize); | 196 LengthResolveType::MaxSize); |
| 197 extent = std::min(extent, max); | 197 extent = std::min(extent, max); |
| 198 } | 198 } |
| 199 | 199 |
| 200 LayoutUnit min = | 200 LayoutUnit min = |
| 201 resolveInlineLength(constraintSpace, style, style.logicalMinWidth(), | 201 ResolveInlineLength(constraintSpace, style, style.logicalMinWidth(), |
| 202 LengthResolveType::MinSize); | 202 LengthResolveType::MinSize); |
| 203 extent = std::max(extent, min); | 203 extent = std::max(extent, min); |
| 204 return extent; | 204 return extent; |
| 205 } | 205 } |
| 206 | 206 |
| 207 LayoutUnit computeBlockSizeForFragment(const NGConstraintSpace& constraintSpace, | 207 LayoutUnit ComputeBlockSizeForFragment(const NGConstraintSpace& constraintSpace, |
| 208 const ComputedStyle& style, | 208 const ComputedStyle& style, |
| 209 LayoutUnit contentSize) { | 209 LayoutUnit contentSize) { |
| 210 if (constraintSpace.FixedBlockSize()) | 210 if (constraintSpace.FixedBlockSize()) |
| 211 return constraintSpace.ContainerSize().block_size; | 211 return constraintSpace.ContainerSize().block_size; |
| 212 | 212 |
| 213 LayoutUnit extent = | 213 LayoutUnit extent = |
| 214 resolveBlockLength(constraintSpace, style, style.logicalHeight(), | 214 ResolveBlockLength(constraintSpace, style, style.logicalHeight(), |
| 215 contentSize, LengthResolveType::ContentSize); | 215 contentSize, LengthResolveType::ContentSize); |
| 216 if (extent == NGSizeIndefinite) { | 216 if (extent == NGSizeIndefinite) { |
| 217 DCHECK_EQ(contentSize, NGSizeIndefinite); | 217 DCHECK_EQ(contentSize, NGSizeIndefinite); |
| 218 return extent; | 218 return extent; |
| 219 } | 219 } |
| 220 | 220 |
| 221 Length maxLength = style.logicalMaxHeight(); | 221 Length maxLength = style.logicalMaxHeight(); |
| 222 if (!maxLength.isMaxSizeNone()) { | 222 if (!maxLength.isMaxSizeNone()) { |
| 223 LayoutUnit max = | 223 LayoutUnit max = |
| 224 resolveBlockLength(constraintSpace, style, maxLength, contentSize, | 224 ResolveBlockLength(constraintSpace, style, maxLength, contentSize, |
| 225 LengthResolveType::MaxSize); | 225 LengthResolveType::MaxSize); |
| 226 extent = std::min(extent, max); | 226 extent = std::min(extent, max); |
| 227 } | 227 } |
| 228 | 228 |
| 229 LayoutUnit min = | 229 LayoutUnit min = |
| 230 resolveBlockLength(constraintSpace, style, style.logicalMinHeight(), | 230 ResolveBlockLength(constraintSpace, style, style.logicalMinHeight(), |
| 231 contentSize, LengthResolveType::MinSize); | 231 contentSize, LengthResolveType::MinSize); |
| 232 extent = std::max(extent, min); | 232 extent = std::max(extent, min); |
| 233 return extent; | 233 return extent; |
| 234 } | 234 } |
| 235 | 235 |
| 236 NGBoxStrut computeMargins(const NGConstraintSpace& constraintSpace, | 236 NGBoxStrut ComputeMargins(const NGConstraintSpace& constraintSpace, |
| 237 const ComputedStyle& style, | 237 const ComputedStyle& style, |
| 238 const NGWritingMode writing_mode, | 238 const NGWritingMode writing_mode, |
| 239 const NGDirection direction) { | 239 const NGDirection direction) { |
| 240 // Margins always get computed relative to the inline size: | 240 // Margins always get computed relative to the inline size: |
| 241 // https://www.w3.org/TR/CSS2/box.html#value-def-margin-width | 241 // https://www.w3.org/TR/CSS2/box.html#value-def-margin-width |
| 242 NGPhysicalDimensions physical_dim; | 242 NGPhysicalDimensions physical_dim; |
| 243 physical_dim.left = | 243 physical_dim.left = |
| 244 resolveInlineLength(constraintSpace, style, style.marginLeft(), | 244 ResolveInlineLength(constraintSpace, style, style.marginLeft(), |
| 245 LengthResolveType::MarginBorderPaddingSize); | 245 LengthResolveType::MarginBorderPaddingSize); |
| 246 physical_dim.right = | 246 physical_dim.right = |
| 247 resolveInlineLength(constraintSpace, style, style.marginRight(), | 247 ResolveInlineLength(constraintSpace, style, style.marginRight(), |
| 248 LengthResolveType::MarginBorderPaddingSize); | 248 LengthResolveType::MarginBorderPaddingSize); |
| 249 physical_dim.top = | 249 physical_dim.top = |
| 250 resolveInlineLength(constraintSpace, style, style.marginTop(), | 250 ResolveInlineLength(constraintSpace, style, style.marginTop(), |
| 251 LengthResolveType::MarginBorderPaddingSize); | 251 LengthResolveType::MarginBorderPaddingSize); |
| 252 physical_dim.bottom = | 252 physical_dim.bottom = |
| 253 resolveInlineLength(constraintSpace, style, style.marginBottom(), | 253 ResolveInlineLength(constraintSpace, style, style.marginBottom(), |
| 254 LengthResolveType::MarginBorderPaddingSize); | 254 LengthResolveType::MarginBorderPaddingSize); |
| 255 return ToLogicalDimensions(physical_dim, writing_mode, direction); | 255 return ToLogicalDimensions(physical_dim, writing_mode, direction); |
| 256 } | 256 } |
| 257 | 257 |
| 258 NGBoxStrut computeBorders(const ComputedStyle& style) { | 258 NGBoxStrut ComputeBorders(const ComputedStyle& style) { |
| 259 NGBoxStrut borders; | 259 NGBoxStrut borders; |
| 260 borders.inline_start = LayoutUnit(style.borderStartWidth()); | 260 borders.inline_start = LayoutUnit(style.borderStartWidth()); |
| 261 borders.inline_end = LayoutUnit(style.borderEndWidth()); | 261 borders.inline_end = LayoutUnit(style.borderEndWidth()); |
| 262 borders.block_start = LayoutUnit(style.borderBeforeWidth()); | 262 borders.block_start = LayoutUnit(style.borderBeforeWidth()); |
| 263 borders.block_end = LayoutUnit(style.borderAfterWidth()); | 263 borders.block_end = LayoutUnit(style.borderAfterWidth()); |
| 264 return borders; | 264 return borders; |
| 265 } | 265 } |
| 266 | 266 |
| 267 NGBoxStrut computePadding(const NGConstraintSpace& constraintSpace, | 267 NGBoxStrut ComputePadding(const NGConstraintSpace& constraintSpace, |
| 268 const ComputedStyle& style) { | 268 const ComputedStyle& style) { |
| 269 // Padding always gets computed relative to the inline size: | 269 // Padding always gets computed relative to the inline size: |
| 270 // https://www.w3.org/TR/CSS2/box.html#value-def-padding-width | 270 // https://www.w3.org/TR/CSS2/box.html#value-def-padding-width |
| 271 NGBoxStrut padding; | 271 NGBoxStrut padding; |
| 272 padding.inline_start = | 272 padding.inline_start = |
| 273 resolveInlineLength(constraintSpace, style, style.paddingStart(), | 273 ResolveInlineLength(constraintSpace, style, style.paddingStart(), |
| 274 LengthResolveType::MarginBorderPaddingSize); | 274 LengthResolveType::MarginBorderPaddingSize); |
| 275 padding.inline_end = | 275 padding.inline_end = |
| 276 resolveInlineLength(constraintSpace, style, style.paddingEnd(), | 276 ResolveInlineLength(constraintSpace, style, style.paddingEnd(), |
| 277 LengthResolveType::MarginBorderPaddingSize); | 277 LengthResolveType::MarginBorderPaddingSize); |
| 278 padding.block_start = | 278 padding.block_start = |
| 279 resolveInlineLength(constraintSpace, style, style.paddingBefore(), | 279 ResolveInlineLength(constraintSpace, style, style.paddingBefore(), |
| 280 LengthResolveType::MarginBorderPaddingSize); | 280 LengthResolveType::MarginBorderPaddingSize); |
| 281 padding.block_end = | 281 padding.block_end = |
| 282 resolveInlineLength(constraintSpace, style, style.paddingAfter(), | 282 ResolveInlineLength(constraintSpace, style, style.paddingAfter(), |
| 283 LengthResolveType::MarginBorderPaddingSize); | 283 LengthResolveType::MarginBorderPaddingSize); |
| 284 return padding; | 284 return padding; |
| 285 } | 285 } |
| 286 | 286 |
| 287 void ApplyAutoMargins(const NGConstraintSpace& constraint_space, | 287 void ApplyAutoMargins(const NGConstraintSpace& constraint_space, |
| 288 const ComputedStyle& style, | 288 const ComputedStyle& style, |
| 289 const NGFragment& fragment, | 289 const NGFragment& fragment, |
| 290 NGBoxStrut& margins) { | 290 NGBoxStrut& margins) { |
| 291 const LayoutUnit used_space = fragment.InlineSize() + margins.InlineSum(); | 291 const LayoutUnit used_space = fragment.InlineSize() + margins.InlineSum(); |
| 292 const LayoutUnit available_space = | 292 const LayoutUnit available_space = |
| 293 constraint_space.ContainerSize().inline_size - used_space; | 293 constraint_space.ContainerSize().inline_size - used_space; |
| 294 if (available_space < LayoutUnit()) | 294 if (available_space < LayoutUnit()) |
| 295 return; | 295 return; |
| 296 if (style.marginStart().isAuto() && style.marginEnd().isAuto()) { | 296 if (style.marginStart().isAuto() && style.marginEnd().isAuto()) { |
| 297 margins.inline_start = available_space / 2; | 297 margins.inline_start = available_space / 2; |
| 298 margins.inline_end = available_space - margins.inline_start; | 298 margins.inline_end = available_space - margins.inline_start; |
| 299 } else if (style.marginStart().isAuto()) { | 299 } else if (style.marginStart().isAuto()) { |
| 300 margins.inline_start = available_space; | 300 margins.inline_start = available_space; |
| 301 } else if (style.marginEnd().isAuto()) { | 301 } else if (style.marginEnd().isAuto()) { |
| 302 margins.inline_end = available_space; | 302 margins.inline_end = available_space; |
| 303 } | 303 } |
| 304 } | 304 } |
| 305 | 305 |
| 306 } // namespace blink | 306 } // namespace blink |
| OLD | NEW |