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

Unified Diff: third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp

Issue 1639723003: [css-flexbox] Use correct aspect ratio for min-size: auto (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review comments Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..f589bc10dd9940647f92964093bf09969095937d 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,44 @@ 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::computeMainSizeFromAspectRatioUsing(const LayoutBox& child, Length crossSizeLength) const
+{
+ ASSERT(hasAspectRatio(child));
+ ASSERT(child.intrinsicSize().height() != 0);
+
+ 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 +693,20 @@ 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;
+ }
+ // TODO(cbiesinger): Eventually we should support other types of sizes here. Requires updating
+ // computeMainSizeFromAspectRatioUsing.
+ return length.isFixed();
+}
+
bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(const LayoutBox& child) const
{
return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && (
@@ -919,6 +976,8 @@ LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(const LayoutBox& child
// css-flexbox section 4.5
LayoutUnit contentSize = computeMainAxisExtentForChild(child, MinSize, Length(MinContent));
ASSERT(contentSize >= 0);
+ if (hasAspectRatio(child) && child.intrinsicSize().height() > 0)
+ contentSize = adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, contentSize);
if (maxExtent != -1 && contentSize > maxExtent)
contentSize = maxExtent;
@@ -929,15 +988,38 @@ LayoutUnit LayoutFlexibleBox::adjustChildSizeForMinAndMax(const LayoutBox& child
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 = computeMainSizeFromAspectRatioUsing(child, crossSizeLength);
+ transferredSize = adjustChildSizeForAspectRatioCrossAxisMinAndMax(child, transferredSize);
+ 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);
}
+LayoutUnit LayoutFlexibleBox::adjustChildSizeForAspectRatioCrossAxisMinAndMax(const LayoutBox& child, LayoutUnit childSize)
+{
+ Length crossMin = isHorizontalFlow() ? child.style()->minHeight() : child.style()->minWidth();
+ Length crossMax = isHorizontalFlow() ? child.style()->maxHeight() : child.style()->maxWidth();
+
+
+ if (crossAxisLengthIsDefinite(child, crossMax)) {
+ LayoutUnit maxValue = computeMainSizeFromAspectRatioUsing(child, crossMax);
+ childSize = std::min(maxValue, childSize);
+ }
+
+ if (crossAxisLengthIsDefinite(child, crossMin)) {
+ LayoutUnit minValue = computeMainSizeFromAspectRatioUsing(child, crossMin);
+ childSize = std::max(minValue, childSize);
+ }
+
+ return childSize;
+}
+
bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayoutChildren)
{
orderedChildren.clear();
@@ -1177,6 +1259,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 +1289,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());
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698