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

Side by Side 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: Created 4 years, 10 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
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutFlexibleBox.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 LayoutUnit LayoutFlexibleBox::crossAxisScrollbarExtentForChild(const LayoutBox& child) const 618 LayoutUnit LayoutFlexibleBox::crossAxisScrollbarExtentForChild(const LayoutBox& child) const
619 { 619 {
620 return isHorizontalFlow() ? child.horizontalScrollbarHeight() : child.vertic alScrollbarWidth(); 620 return isHorizontalFlow() ? child.horizontalScrollbarHeight() : child.vertic alScrollbarWidth();
621 } 621 }
622 622
623 LayoutPoint LayoutFlexibleBox::flowAwareLocationForChild(const LayoutBox& child) const 623 LayoutPoint LayoutFlexibleBox::flowAwareLocationForChild(const LayoutBox& child) const
624 { 624 {
625 return isHorizontalFlow() ? child.location() : child.location().transposedPo int(); 625 return isHorizontalFlow() ? child.location() : child.location().transposedPo int();
626 } 626 }
627 627
628 bool LayoutFlexibleBox::useChildAspectRatio(const LayoutBox& child) const
629 {
630 if (!child.isImage() && !child.isCanvas() && !child.isVideo())
631 return false;
632 if (child.intrinsicSize().height() == 0) {
633 // We can't compute a ratio in this case.
634 return false;
635 }
636 Length crossSize;
637 if (isHorizontalFlow())
638 crossSize = child.styleRef().height();
leviw_travelin_and_unemployed 2016/01/27 04:53:56 Do we have tests for both these codepaths?
cbiesinger 2016/01/27 21:42:56 Complicated question... Short answer, yes, flex-m
leviw_travelin_and_unemployed 2016/01/27 23:18:45 Word :)
639 else
640 crossSize = child.styleRef().width();
641 return crossAxisLengthIsDefinite(child, crossSize);
642 }
643
644 LayoutUnit LayoutFlexibleBox::computeMainSizeFromAspectRatio(const LayoutBox& ch ild, LayoutUnit crossSize) const
645 {
646 ASSERT(useChildAspectRatio(child));
647 const LayoutSize& childIntrinsicSize = child.intrinsicSize();
648 double ratio = childIntrinsicSize.width().toFloat() / childIntrinsicSize.hei ght().toFloat();
649 if (isHorizontalFlow())
leviw_travelin_and_unemployed 2016/01/27 04:53:56 Ditto.
650 return crossSize * ratio;
651 return crossSize / ratio;
652 }
653
628 void LayoutFlexibleBox::setFlowAwareLocationForChild(LayoutBox& child, const Lay outPoint& location) 654 void LayoutFlexibleBox::setFlowAwareLocationForChild(LayoutBox& child, const Lay outPoint& location)
629 { 655 {
630 if (isHorizontalFlow()) 656 if (isHorizontalFlow())
631 child.setLocationAndUpdateOverflowControlsIfNeeded(location); 657 child.setLocationAndUpdateOverflowControlsIfNeeded(location);
632 else 658 else
633 child.setLocationAndUpdateOverflowControlsIfNeeded(location.transposedPo int()); 659 child.setLocationAndUpdateOverflowControlsIfNeeded(location.transposedPo int());
634 } 660 }
635 661
636 LayoutUnit LayoutFlexibleBox::mainAxisBorderAndPaddingExtentForChild(const Layou tBox& child) const 662 LayoutUnit LayoutFlexibleBox::mainAxisBorderAndPaddingExtentForChild(const Layou tBox& child) const
637 { 663 {
638 return isHorizontalFlow() ? child.borderAndPaddingWidth() : child.borderAndP addingHeight(); 664 return isHorizontalFlow() ? child.borderAndPaddingWidth() : child.borderAndP addingHeight();
639 } 665 }
640 666
641 bool LayoutFlexibleBox::mainAxisLengthIsDefinite(const LayoutBox& child, const L ength& flexBasis) const 667 bool LayoutFlexibleBox::mainAxisLengthIsDefinite(const LayoutBox& child, const L ength& flexBasis) const
642 { 668 {
643 if (flexBasis.isAuto()) 669 if (flexBasis.isAuto())
644 return false; 670 return false;
645 if (flexBasis.hasPercent()) { 671 if (flexBasis.hasPercent()) {
646 return isColumnFlow() ? 672 return isColumnFlow() ?
647 child.computePercentageLogicalHeight(flexBasis) != -1 : 673 child.computePercentageLogicalHeight(flexBasis) != -1 :
648 hasDefiniteLogicalWidth(); 674 hasDefiniteLogicalWidth();
649 } 675 }
650 return true; 676 return true;
651 } 677 }
652 678
679 bool LayoutFlexibleBox::crossAxisLengthIsDefinite(const LayoutBox& child, const Length& length) const
leviw_travelin_and_unemployed 2016/01/27 04:53:56 Damn, it's back :(
cbiesinger 2016/01/27 21:42:56 Hm? What do you mean?
leviw_travelin_and_unemployed 2016/01/27 23:18:45 Is this not a method that existed previously?
cbiesinger 2016/01/27 23:25:25 I don't *believe* so but I'm actually not sure...
680 {
681 if (length.isAuto())
682 return false;
683 if (length.hasPercent()) {
684 return hasOrthogonalFlow(child) ?
685 hasDefiniteLogicalWidth() :
686 child.computePercentageLogicalHeight(length) != -1;
687
688 }
689 return true;
690 }
691
653 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(const LayoutBox& child) const 692 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(const LayoutBox& child) const
654 { 693 {
655 return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && ( 694 return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && (
656 hasOrthogonalFlow(child) || crossAxisOverflowForChild(child) == OAUTO); 695 hasOrthogonalFlow(child) || crossAxisOverflowForChild(child) == OAUTO);
657 } 696 }
658 697
659 LayoutUnit LayoutFlexibleBox::computeInnerFlexBaseSizeForChild(LayoutBox& child, ChildLayoutType childLayoutType) 698 LayoutUnit LayoutFlexibleBox::computeInnerFlexBaseSizeForChild(LayoutBox& child, ChildLayoutType childLayoutType)
660 { 699 {
661 child.clearOverrideSize(); 700 child.clearOverrideSize();
662 701
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 // css-flexbox section 4.5 955 // css-flexbox section 4.5
917 LayoutUnit contentSize = computeMainAxisExtentForChild(child, MinSize, L ength(MinContent)); 956 LayoutUnit contentSize = computeMainAxisExtentForChild(child, MinSize, L ength(MinContent));
918 ASSERT(contentSize >= 0); 957 ASSERT(contentSize >= 0);
919 if (maxExtent != -1 && contentSize > maxExtent) 958 if (maxExtent != -1 && contentSize > maxExtent)
920 contentSize = maxExtent; 959 contentSize = maxExtent;
921 960
922 Length mainSize = isHorizontalFlow() ? child.styleRef().width() : child. styleRef().height(); 961 Length mainSize = isHorizontalFlow() ? child.styleRef().width() : child. styleRef().height();
923 if (mainAxisLengthIsDefinite(child, mainSize)) { 962 if (mainAxisLengthIsDefinite(child, mainSize)) {
924 LayoutUnit resolvedMainSize = computeMainAxisExtentForChild(child, M ainOrPreferredSize, mainSize); 963 LayoutUnit resolvedMainSize = computeMainAxisExtentForChild(child, M ainOrPreferredSize, mainSize);
925 ASSERT(resolvedMainSize >= 0); 964 ASSERT(resolvedMainSize >= 0);
965 // TODO(cbiesinger): For items with an aspect ratio, clamp this size through the converted cross-size min/max size. crbug.com/249112
926 LayoutUnit specifiedSize = maxExtent != -1 ? std::min(resolvedMainSi ze, maxExtent) : resolvedMainSize; 966 LayoutUnit specifiedSize = maxExtent != -1 ? std::min(resolvedMainSi ze, maxExtent) : resolvedMainSize;
927 967
928 minExtent = std::min(specifiedSize, contentSize); 968 minExtent = std::min(specifiedSize, contentSize);
969 } else if (useChildAspectRatio(child)) {
970 Length crossSizeLength = isHorizontalFlow() ? child.styleRef().heigh t() : child.styleRef().width();
971 LayoutUnit crossSize;
972 if (crossSizeLength.isFixed()) {
973 crossSize = crossSizeLength.value();
974 } else {
975 ASSERT(crossSizeLength.hasPercent());
976 crossSize = hasOrthogonalFlow(child) ?
977 adjustBorderBoxLogicalWidthForBoxSizing(valueForLength(cross SizeLength, contentWidth())) :
978 child.computePercentageLogicalHeight(crossSizeLength);
979 }
980 LayoutUnit transferredSize = computeMainSizeFromAspectRatio(child, c rossSize);
981 minExtent = std::min(transferredSize, contentSize);
929 } else { 982 } else {
930 minExtent = contentSize; 983 minExtent = contentSize;
931 } 984 }
932 // TODO(cbiesinger): Implement aspect ratio handling (here, transferred size) - crbug.com/249112
933 } 985 }
934 ASSERT(minExtent >= 0); 986 ASSERT(minExtent >= 0);
935 return std::max(childSize, minExtent); 987 return std::max(childSize, minExtent);
936 } 988 }
937 989
938 bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren , LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalFlexShrink, d ouble& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayo utChildren) 990 bool LayoutFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren , LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalFlexShrink, d ouble& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool relayo utChildren)
939 { 991 {
940 orderedChildren.clear(); 992 orderedChildren.clear();
941 sumFlexBaseSize = 0; 993 sumFlexBaseSize = 0;
942 totalFlexGrow = totalFlexShrink = totalWeightedFlexShrink = 0; 994 totalFlexGrow = totalFlexShrink = totalWeightedFlexShrink = 0;
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 // So the child will automatically stretch if our cross axis is the child's inline axis. That's the case if: 1219 // So the child will automatically stretch if our cross axis is the child's inline axis. That's the case if:
1168 // - We are horizontal and the child is in vertical writing mode 1220 // - We are horizontal and the child is in vertical writing mode
1169 // - We are vertical and the child is in horizontal writing mode 1221 // - We are vertical and the child is in horizontal writing mode
1170 // Otherwise, we need to stretch if the cross axis size is auto. 1222 // Otherwise, we need to stretch if the cross axis size is auto.
1171 if (alignmentForChild(child) != ItemPositionStretch) 1223 if (alignmentForChild(child) != ItemPositionStretch)
1172 return false; 1224 return false;
1173 1225
1174 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) 1226 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode())
1175 return false; 1227 return false;
1176 1228
1229 // TODO(cbiesinger): what about indefinite percentage heights?
1177 return isHorizontalFlow() ? child.styleRef().height().isAuto() : child.style Ref().width().isAuto(); 1230 return isHorizontalFlow() ? child.styleRef().height().isAuto() : child.style Ref().width().isAuto();
1178 } 1231 }
1179 1232
1180 bool LayoutFlexibleBox::childHasIntrinsicMainAxisSize(const LayoutBox& child) co nst 1233 bool LayoutFlexibleBox::childHasIntrinsicMainAxisSize(const LayoutBox& child) co nst
1181 { 1234 {
1182 bool result = false; 1235 bool result = false;
1183 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) { 1236 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) {
1184 Length childFlexBasis = flexBasisForChild(child); 1237 Length childFlexBasis = flexBasisForChild(child);
1185 Length childMinSize = isHorizontalFlow() ? child.style()->minWidth() : c hild.style()->minHeight(); 1238 Length childMinSize = isHorizontalFlow() ? child.style()->minWidth() : c hild.style()->minHeight();
1186 Length childMaxSize = isHorizontalFlow() ? child.style()->maxWidth() : c hild.style()->maxHeight(); 1239 Length childMaxSize = isHorizontalFlow() ? child.style()->maxWidth() : c hild.style()->maxHeight();
1187 if (childFlexBasis.isIntrinsic() || childMinSize.isIntrinsicOrAuto() || childMaxSize.isIntrinsic()) 1240 if (childFlexBasis.isIntrinsic() || childMinSize.isIntrinsicOrAuto() || childMaxSize.isIntrinsic())
1188 result = true; 1241 result = true;
1189 } 1242 }
1190 return result; 1243 return result;
1191 } 1244 }
1192 1245
1193 EOverflow LayoutFlexibleBox::mainAxisOverflowForChild(const LayoutBox& child) co nst 1246 EOverflow LayoutFlexibleBox::mainAxisOverflowForChild(const LayoutBox& child) co nst
1194 { 1247 {
1195 if (isHorizontalFlow()) 1248 if (isHorizontalFlow())
1196 return child.styleRef().overflowX(); 1249 return child.styleRef().overflowX();
1197 return child.styleRef().overflowY(); 1250 return child.styleRef().overflowY();
1198 } 1251 }
1199 1252
1200 EOverflow LayoutFlexibleBox::crossAxisOverflowForChild(const LayoutBox& child) c onst 1253 EOverflow LayoutFlexibleBox::crossAxisOverflowForChild(const LayoutBox& child) c onst
1201 { 1254 {
1202 if (isHorizontalFlow()) 1255 if (isHorizontalFlow())
1203 return child.styleRef().overflowY(); 1256 return child.styleRef().overflowY();
1204 return child.styleRef().overflowX(); 1257 return child.styleRef().overflowX();
1205 } 1258 }
1259
1206 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope , Vector<LineContext>& lineContexts) 1260 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope , Vector<LineContext>& lineContexts)
1207 { 1261 {
1208 ASSERT(childSizes.size() == children.size()); 1262 ASSERT(childSizes.size() == children.size());
1209 1263
1210 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children); 1264 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children);
1211 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace); 1265 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace);
1212 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ; 1266 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ;
1213 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContentPosition(), style()->justifyContentDistribution(), numberOfChildren ForJustifyContent); 1267 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContentPosition(), style()->justifyContentDistribution(), numberOfChildren ForJustifyContent);
1214 if (style()->flexDirection() == FlowRowReverse) 1268 if (style()->flexDirection() == FlowRowReverse)
1215 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight(); 1269 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight();
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 ASSERT(child); 1596 ASSERT(child);
1543 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; 1597 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent;
1544 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; 1598 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge;
1545 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; 1599 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent;
1546 adjustAlignmentForChild(*child, newOffset - originalOffset); 1600 adjustAlignmentForChild(*child, newOffset - originalOffset);
1547 } 1601 }
1548 } 1602 }
1549 } 1603 }
1550 1604
1551 } // namespace blink 1605 } // namespace blink
OLDNEW
« 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