Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp |
| index f735ab00a391df20b08aabec6cc348f1ae456e59..fd997c69763684f74286088cd0c98f9a7f8d2a43 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp |
| @@ -42,6 +42,11 @@ |
| namespace blink { |
| +static bool hasAspectRatio(const LayoutBox& child) |
| +{ |
| + return child.isImage() || child.isCanvas() || child.isVideo(); |
| +} |
| + |
| struct LayoutFlexibleBox::LineContext { |
| LineContext(LayoutUnit crossAxisOffset, LayoutUnit crossAxisExtent, size_t numberOfChildren, LayoutUnit maxAscent) |
| : crossAxisOffset(crossAxisOffset) |
| @@ -452,7 +457,7 @@ LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(const LayoutBox& chi |
| // computeLogicalWidth always re-computes the intrinsic widths. However, when our logical width is auto, |
| // we can just use our cached value. So let's do that here. (Compare code in LayoutBlock::computePreferredLogicalWidths) |
| LayoutUnit borderAndPadding = child.borderAndPaddingLogicalWidth(); |
| - if (child.styleRef().logicalWidth().isAuto()) { |
| + if (child.styleRef().logicalWidth().isAuto() && !hasAspectRatio(child)) { |
| if (size.type() == MinContent) |
| return child.minPreferredLogicalWidth() - borderAndPadding; |
| if (size.type() == MaxContent) |
| @@ -625,6 +630,43 @@ LayoutPoint LayoutFlexibleBox::flowAwareLocationForChild(const LayoutBox& child) |
| return isHorizontalFlow() ? child.location() : child.location().transposedPoint(); |
| } |
| +bool LayoutFlexibleBox::useChildAspectRatio(const LayoutBox& child) const |
| +{ |
| + if (!hasAspectRatio(child)) |
| + return false; |
| + if (child.intrinsicSize().height() == 0) { |
| + // We can't compute a ratio in this case. |
| + return false; |
| + } |
| + Length crossSize; |
| + if (isHorizontalFlow()) |
| + crossSize = child.styleRef().height(); |
| + else |
| + crossSize = child.styleRef().width(); |
| + return crossAxisLengthIsDefinite(child, crossSize); |
| +} |
| + |
| +LayoutUnit LayoutFlexibleBox::computeMainSizeFromAspectRatio(const LayoutBox& child, Length crossSizeLength) const |
| +{ |
| + ASSERT(useChildAspectRatio(child)); |
| + |
| + LayoutUnit crossSize; |
| + if (crossSizeLength.isFixed()) { |
| + crossSize = crossSizeLength.value(); |
| + } else { |
| + ASSERT(crossSizeLength.hasPercent()); |
| + crossSize = hasOrthogonalFlow(child) ? |
| + adjustBorderBoxLogicalWidthForBoxSizing(valueForLength(crossSizeLength, contentWidth())) : |
| + child.computePercentageLogicalHeight(crossSizeLength); |
| + } |
| + |
| + const LayoutSize& childIntrinsicSize = child.intrinsicSize(); |
| + double ratio = childIntrinsicSize.width().toFloat() / childIntrinsicSize.height().toFloat(); |
| + if (isHorizontalFlow()) |
| + return crossSize * ratio; |
| + return crossSize / ratio; |
| +} |
| + |
| void LayoutFlexibleBox::setFlowAwareLocationForChild(LayoutBox& child, const LayoutPoint& location) |
| { |
| if (isHorizontalFlow()) |
| @@ -650,6 +692,19 @@ bool LayoutFlexibleBox::mainAxisLengthIsDefinite(const LayoutBox& child, const L |
| return true; |
| } |
| +bool LayoutFlexibleBox::crossAxisLengthIsDefinite(const LayoutBox& child, const Length& length) const |
| +{ |
| + if (length.isAuto()) |
| + return false; |
| + if (length.hasPercent()) { |
| + return hasOrthogonalFlow(child) ? |
| + hasDefiniteLogicalWidth() : |
| + child.computePercentageLogicalHeight(length) != -1; |
| + |
|
leviw_travelin_and_unemployed
2016/01/27 23:18:45
This seems like a weird empty line </whitespace-je
cbiesinger
2016/01/27 23:25:25
Oh oops. Removed.
|
| + } |
| + return true; |
| +} |
| + |
| bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(const LayoutBox& child) const |
| { |
| return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && ( |
| @@ -926,13 +981,17 @@ LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(const LayoutBox& child |
| if (mainAxisLengthIsDefinite(child, mainSize)) { |
| LayoutUnit resolvedMainSize = computeMainAxisExtentForChild(child, MainOrPreferredSize, mainSize); |
| ASSERT(resolvedMainSize >= 0); |
| + // TODO(cbiesinger): For items with an aspect ratio, clamp this size through the converted cross-size min/max size. crbug.com/249112 |
| LayoutUnit specifiedSize = maxExtent != -1 ? std::min(resolvedMainSize, maxExtent) : resolvedMainSize; |
| minExtent = std::min(specifiedSize, contentSize); |
| + } else if (useChildAspectRatio(child)) { |
| + Length crossSizeLength = isHorizontalFlow() ? child.styleRef().height() : child.styleRef().width(); |
| + LayoutUnit transferredSize = computeMainSizeFromAspectRatio(child, crossSizeLength); |
| + minExtent = std::min(transferredSize, contentSize); |
| } else { |
| minExtent = contentSize; |
| } |
| - // TODO(cbiesinger): Implement aspect ratio handling (here, transferred size) - crbug.com/249112 |
| } |
| ASSERT(minExtent >= 0); |
| return std::max(childSize, minExtent); |
| @@ -1177,6 +1236,7 @@ bool LayoutFlexibleBox::needToStretchChildLogicalHeight(const LayoutBox& child) |
| if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) |
| return false; |
| + // TODO(cbiesinger): what about indefinite percentage heights? |
| return isHorizontalFlow() ? child.styleRef().height().isAuto() : child.styleRef().width().isAuto(); |
| } |
| @@ -1206,6 +1266,7 @@ EOverflow LayoutFlexibleBox::crossAxisOverflowForChild(const LayoutBox& child) c |
| return child.styleRef().overflowY(); |
| return child.styleRef().overflowX(); |
| } |
| + |
| void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, LayoutUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope, Vector<LineContext>& lineContexts) |
| { |
| ASSERT(childSizes.size() == children.size()); |