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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp

Issue 2097663002: Refactor flexbox layout a bit (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 , maxAscent(maxAscent) 55 , maxAscent(maxAscent)
56 { 56 {
57 } 57 }
58 58
59 LayoutUnit crossAxisOffset; 59 LayoutUnit crossAxisOffset;
60 LayoutUnit crossAxisExtent; 60 LayoutUnit crossAxisExtent;
61 size_t numberOfChildren; 61 size_t numberOfChildren;
62 LayoutUnit maxAscent; 62 LayoutUnit maxAscent;
63 }; 63 };
64 64
65 struct LayoutFlexibleBox::Violation { 65 struct LayoutFlexibleBox::FlexItem {
66 Violation(LayoutBox* child, LayoutUnit childSize, LayoutUnit childInnerFlexB aseSize) 66 FlexItem(LayoutBox* box, LayoutUnit innerFlexBaseSize, LayoutUnit hypothetic alMainSize)
67 : child(child) 67 : box(box)
68 , childSize(childSize) 68 , innerFlexBaseSize(innerFlexBaseSize)
69 , childInnerFlexBaseSize(childInnerFlexBaseSize) 69 , hypotheticalMainSize(hypotheticalMainSize)
70 , frozen(false)
70 { 71 {
71 } 72 }
72 73
73 LayoutBox* child; 74 // This constructor is used for out-of-flow children
74 LayoutUnit childSize; 75 explicit FlexItem(LayoutBox* box)
75 LayoutUnit childInnerFlexBaseSize; 76 : box(box)
77 , innerFlexBaseSize()
78 , hypotheticalMainSize()
79 , frozen(true)
80 {
81 }
82 LayoutBox* box;
83 const LayoutUnit innerFlexBaseSize;
84 const LayoutUnit hypotheticalMainSize;
85 LayoutUnit flexedContentSize;
86 bool frozen;
76 }; 87 };
77 88
78
79 LayoutFlexibleBox::LayoutFlexibleBox(Element* element) 89 LayoutFlexibleBox::LayoutFlexibleBox(Element* element)
80 : LayoutBlock(element) 90 : LayoutBlock(element)
81 , m_orderIterator(this) 91 , m_orderIterator(this)
82 , m_numberOfInFlowChildrenOnFirstLine(-1) 92 , m_numberOfInFlowChildrenOnFirstLine(-1)
83 { 93 {
84 ASSERT(!childrenInline()); 94 ASSERT(!childrenInline());
85 } 95 }
86 96
87 LayoutFlexibleBox::~LayoutFlexibleBox() 97 LayoutFlexibleBox::~LayoutFlexibleBox()
88 { 98 {
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 void LayoutFlexibleBox::layoutFlexItems(bool relayoutChildren, SubtreeLayoutScop e& layoutScope) 851 void LayoutFlexibleBox::layoutFlexItems(bool relayoutChildren, SubtreeLayoutScop e& layoutScope)
842 { 852 {
843 Vector<LineContext> lineContexts; 853 Vector<LineContext> lineContexts;
844 OrderedFlexItemList orderedChildren; 854 OrderedFlexItemList orderedChildren;
845 LayoutUnit sumFlexBaseSize; 855 LayoutUnit sumFlexBaseSize;
846 double totalFlexGrow; 856 double totalFlexGrow;
847 double totalFlexShrink; 857 double totalFlexShrink;
848 double totalWeightedFlexShrink; 858 double totalWeightedFlexShrink;
849 LayoutUnit sumHypotheticalMainSize; 859 LayoutUnit sumHypotheticalMainSize;
850 860
851 Vector<LayoutUnit, 16> childSizes;
852
853 PaintLayerScrollableArea::PreventRelayoutScope preventRelayoutScope(layoutSc ope); 861 PaintLayerScrollableArea::PreventRelayoutScope preventRelayoutScope(layoutSc ope);
854 862
855 dirtyForLayoutFromPercentageHeightDescendants(layoutScope); 863 dirtyForLayoutFromPercentageHeightDescendants(layoutScope);
856 864
857 m_orderIterator.first(); 865 m_orderIterator.first();
858 LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefor e(); 866 LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefor e();
859 while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChild ren)) { 867 while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, sumHypotheticalMainSize, relayoutChild ren)) {
860 LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypothetica lMainSize); 868 LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypothetica lMainSize);
861 // availableFreeSpace is the initial amount of free space in this flexbo x. 869 // availableFreeSpace is the initial amount of free space in this flexbo x.
862 // remainingFreeSpace starts out at the same value but as we place and l ay out 870 // remainingFreeSpace starts out at the same value but as we place and l ay out
863 // flex items we subtract from it. Note that both values can be negative . 871 // flex items we subtract from it. Note that both values can be negative .
864 const LayoutUnit availableFreeSpace = containerMainInnerSize - sumFlexBa seSize; 872 const LayoutUnit availableFreeSpace = containerMainInnerSize - sumFlexBa seSize;
865 LayoutUnit remainingFreeSpace = availableFreeSpace; 873 LayoutUnit remainingFreeSpace = availableFreeSpace;
866 FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) ? PositiveFlexibility : NegativeFlexibility; 874 FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) ? PositiveFlexibility : NegativeFlexibility;
867 InflexibleFlexItemSize inflexibleItems; 875 while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeS pace, remainingFreeSpace, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrin k)) {
868 childSizes.reserveCapacity(orderedChildren.size());
869 while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeS pace, remainingFreeSpace, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrin k, inflexibleItems, childSizes)) {
870 ASSERT(totalFlexGrow >= 0 && totalWeightedFlexShrink >= 0); 876 ASSERT(totalFlexGrow >= 0 && totalWeightedFlexShrink >= 0);
871 ASSERT(inflexibleItems.size() > 0);
872 } 877 }
873 878
874 // Recalculate the remaining free space. The adjustment for flex factors between 0..1 means we can't just 879 // Recalculate the remaining free space. The adjustment for flex factors between 0..1 means we can't just
875 // use remainingFreeSpace here. 880 // use remainingFreeSpace here.
876 remainingFreeSpace = containerMainInnerSize; 881 remainingFreeSpace = containerMainInnerSize;
877 for (size_t i = 0; i < orderedChildren.size(); ++i) { 882 for (size_t i = 0; i < orderedChildren.size(); ++i) {
878 LayoutBox* child = orderedChildren[i]; 883 LayoutBox* child = orderedChildren[i].box;
879 if (child->isOutOfFlowPositioned()) 884 if (child->isOutOfFlowPositioned())
880 continue; 885 continue;
881 remainingFreeSpace -= (childSizes[i] + mainAxisBorderAndPaddingExten tForChild(*child) 886 remainingFreeSpace -= (orderedChildren[i].flexedContentSize + mainAx isBorderAndPaddingExtentForChild(*child)
882 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeig ht())); 887 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeig ht()));
883 } 888 }
884 layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, rem ainingFreeSpace, relayoutChildren, layoutScope, lineContexts); 889 layoutAndPlaceChildren(crossAxisOffset, orderedChildren, remainingFreeSp ace, relayoutChildren, layoutScope, lineContexts);
885 } 890 }
886 if (hasLineIfEmpty()) { 891 if (hasLineIfEmpty()) {
887 // Even if computeNextFlexLine returns true, the flexbox might not have 892 // Even if computeNextFlexLine returns true, the flexbox might not have
888 // a line because all our children might be out of flow positioned. 893 // a line because all our children might be out of flow positioned.
889 // Instead of just checking if we have a line, make sure the flexbox 894 // Instead of just checking if we have a line, make sure the flexbox
890 // has at least a line's worth of height to cover this case. 895 // has at least a line's worth of height to cover this case.
891 LayoutUnit minHeight = minimumLogicalHeightForEmptyLine(); 896 LayoutUnit minHeight = minimumLogicalHeightForEmptyLine();
892 if (size().height() < minHeight) 897 if (size().height() < minHeight)
893 setLogicalHeight(minHeight); 898 setLogicalHeight(minHeight);
894 } 899 }
895 900
896 updateLogicalHeight(); 901 updateLogicalHeight();
897 repositionLogicalHeightDependentFlexItems(lineContexts); 902 repositionLogicalHeightDependentFlexItems(lineContexts);
898 } 903 }
899 904
900 LayoutUnit LayoutFlexibleBox::autoMarginOffsetInMainAxis(const OrderedFlexItemLi st& children, LayoutUnit& availableFreeSpace) 905 LayoutUnit LayoutFlexibleBox::autoMarginOffsetInMainAxis(const OrderedFlexItemLi st& children, LayoutUnit& availableFreeSpace)
901 { 906 {
902 if (availableFreeSpace <= LayoutUnit()) 907 if (availableFreeSpace <= LayoutUnit())
903 return LayoutUnit(); 908 return LayoutUnit();
904 909
905 int numberOfAutoMargins = 0; 910 int numberOfAutoMargins = 0;
906 bool isHorizontal = isHorizontalFlow(); 911 bool isHorizontal = isHorizontalFlow();
907 for (size_t i = 0; i < children.size(); ++i) { 912 for (size_t i = 0; i < children.size(); ++i) {
908 LayoutBox* child = children[i]; 913 LayoutBox* child = children[i].box;
909 if (child->isOutOfFlowPositioned()) 914 if (child->isOutOfFlowPositioned())
910 continue; 915 continue;
911 if (isHorizontal) { 916 if (isHorizontal) {
912 if (child->style()->marginLeft().isAuto()) 917 if (child->style()->marginLeft().isAuto())
913 ++numberOfAutoMargins; 918 ++numberOfAutoMargins;
914 if (child->style()->marginRight().isAuto()) 919 if (child->style()->marginRight().isAuto())
915 ++numberOfAutoMargins; 920 ++numberOfAutoMargins;
916 } else { 921 } else {
917 if (child->style()->marginTop().isAuto()) 922 if (child->style()->marginTop().isAuto())
918 ++numberOfAutoMargins; 923 ++numberOfAutoMargins;
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 1189
1185 if (!m_orderIterator.currentChild()) 1190 if (!m_orderIterator.currentChild())
1186 return false; 1191 return false;
1187 1192
1188 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); 1193 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max());
1189 1194
1190 bool lineHasInFlowItem = false; 1195 bool lineHasInFlowItem = false;
1191 1196
1192 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord erIterator.next()) { 1197 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord erIterator.next()) {
1193 if (child->isOutOfFlowPositioned()) { 1198 if (child->isOutOfFlowPositioned()) {
1194 orderedChildren.append(child); 1199 orderedChildren.append(FlexItem(child));
1195 continue; 1200 continue;
1196 } 1201 }
1197 1202
1198 // If this condition is true, then computeMainAxisExtentForChild will ca ll child.intrinsicContentLogicalHeight() 1203 // If this condition is true, then computeMainAxisExtentForChild will ca ll child.intrinsicContentLogicalHeight()
1199 // and child.scrollbarLogicalHeight(), so if the child has intrinsic min /max/preferred size, 1204 // and child.scrollbarLogicalHeight(), so if the child has intrinsic min /max/preferred size,
1200 // run layout on it now to make sure its logical height and scroll bars are up to date. 1205 // run layout on it now to make sure its logical height and scroll bars are up to date.
1201 if (childHasIntrinsicMainAxisSize(*child) && child->needsLayout()) { 1206 if (childHasIntrinsicMainAxisSize(*child) && child->needsLayout()) {
1202 child->clearOverrideSize(); 1207 child->clearOverrideSize();
1203 child->layoutIfNeeded(); 1208 child->layoutIfNeeded();
1204 cacheChildMainSize(*child); 1209 cacheChildMainSize(*child);
1205 } 1210 }
1206 1211
1207 LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(*ch ild, relayoutChildren ? ForceLayout : LayoutIfNeeded); 1212 LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(*ch ild, relayoutChildren ? ForceLayout : LayoutIfNeeded);
1208 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx tentForChild(*child) 1213 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx tentForChild(*child)
1209 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight() ); 1214 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight() );
1210 LayoutUnit childOuterFlexBaseSize = childInnerFlexBaseSize + childMainAx isMarginBorderPadding; 1215 LayoutUnit childOuterFlexBaseSize = childInnerFlexBaseSize + childMainAx isMarginBorderPadding;
1211 1216
1212 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa x(*child, childInnerFlexBaseSize); 1217 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa x(*child, childInnerFlexBaseSize);
1213 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent + childMainAxisMarginBorderPadding; 1218 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent + childMainAxisMarginBorderPadding;
1214 1219
1215 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize > lineBreakLength && lineHasInFlowItem) 1220 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize > lineBreakLength && lineHasInFlowItem)
1216 break; 1221 break;
1217 orderedChildren.append(child); 1222 orderedChildren.append(FlexItem(child, childInnerFlexBaseSize, childMinM axAppliedMainAxisExtent));
1218 lineHasInFlowItem = true; 1223 lineHasInFlowItem = true;
1219 sumFlexBaseSize += childOuterFlexBaseSize; 1224 sumFlexBaseSize += childOuterFlexBaseSize;
1220 totalFlexGrow += child->style()->flexGrow(); 1225 totalFlexGrow += child->style()->flexGrow();
1221 totalFlexShrink += child->style()->flexShrink(); 1226 totalFlexShrink += child->style()->flexShrink();
1222 totalWeightedFlexShrink += child->style()->flexShrink() * childInnerFlex BaseSize; 1227 totalWeightedFlexShrink += child->style()->flexShrink() * childInnerFlex BaseSize;
1223 sumHypotheticalMainSize += childHypotheticalMainSize; 1228 sumHypotheticalMainSize += childHypotheticalMainSize;
1224 } 1229 }
1225 return true; 1230 return true;
1226 } 1231 }
1227 1232
1228 void LayoutFlexibleBox::freezeViolations(const Vector<Violation>& violations, La youtUnit& availableFreeSpace, double& totalFlexGrow, double& totalFlexShrink, do uble& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems) 1233 void LayoutFlexibleBox::freezeViolations(Vector<FlexItem*>& violations, LayoutUn it& availableFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink)
1229 { 1234 {
1230 for (size_t i = 0; i < violations.size(); ++i) { 1235 for (size_t i = 0; i < violations.size(); ++i) {
1231 LayoutBox* child = violations[i].child; 1236 LayoutBox* child = violations[i]->box;
1232 LayoutUnit childSize = violations[i].childSize; 1237 LayoutUnit childSize = violations[i]->flexedContentSize;
1233 availableFreeSpace -= childSize - violations[i].childInnerFlexBaseSize; 1238 availableFreeSpace -= childSize - violations[i]->innerFlexBaseSize;
1234 totalFlexGrow -= child->style()->flexGrow(); 1239 totalFlexGrow -= child->style()->flexGrow();
1235 totalFlexShrink -= child->style()->flexShrink(); 1240 totalFlexShrink -= child->style()->flexShrink();
1236 totalWeightedFlexShrink -= child->style()->flexShrink() * violations[i]. childInnerFlexBaseSize; 1241 totalWeightedFlexShrink -= child->style()->flexShrink() * violations[i]- >innerFlexBaseSize;
1237 // totalWeightedFlexShrink can be negative when we exceed the precision of a double when we initially 1242 // totalWeightedFlexShrink can be negative when we exceed the precision of a double when we initially
1238 // calcuate totalWeightedFlexShrink. We then subtract each child's weigh ted flex shrink with full precision, 1243 // calcuate totalWeightedFlexShrink. We then subtract each child's weigh ted flex shrink with full precision,
1239 // now leading to a negative result. See css3/flexbox/large-flex-shrink- assert.html 1244 // now leading to a negative result. See css3/flexbox/large-flex-shrink- assert.html
1240 totalWeightedFlexShrink = std::max(totalWeightedFlexShrink, 0.0); 1245 totalWeightedFlexShrink = std::max(totalWeightedFlexShrink, 0.0);
1241 inflexibleItems.set(child, childSize); 1246 violations[i]->frozen = true;
1242 } 1247 }
1243 } 1248 }
1244 1249
1245 // Returns true if we successfully ran the algorithm and sized the flex items. 1250 // Returns true if we successfully ran the algorithm and sized the flex items.
1246 bool LayoutFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedF lexItemList& children, LayoutUnit availableFreeSpace, LayoutUnit& remainingFreeS pace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexS hrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit, 16>& childSiz es) 1251 bool LayoutFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, OrderedFlexIte mList& children, LayoutUnit availableFreeSpace, LayoutUnit& remainingFreeSpace, double& totalFlexGrow, double& totalFlexShrink, double& totalWeightedFlexShrink)
1247 { 1252 {
1248 childSizes.resize(0);
1249 LayoutUnit totalViolation; 1253 LayoutUnit totalViolation;
1250 LayoutUnit usedFreeSpace; 1254 LayoutUnit usedFreeSpace;
1251 Vector<Violation> minViolations; 1255 Vector<FlexItem*> minViolations;
1252 Vector<Violation> maxViolations; 1256 Vector<FlexItem*> maxViolations;
1253 1257
1254 double sumFlexFactors = (flexSign == PositiveFlexibility) ? totalFlexGrow : totalFlexShrink; 1258 double sumFlexFactors = (flexSign == PositiveFlexibility) ? totalFlexGrow : totalFlexShrink;
1255 if (sumFlexFactors > 0 && sumFlexFactors < 1) { 1259 if (sumFlexFactors > 0 && sumFlexFactors < 1) {
1256 LayoutUnit fractional(availableFreeSpace * sumFlexFactors); 1260 LayoutUnit fractional(availableFreeSpace * sumFlexFactors);
1257 if (fractional.abs() < remainingFreeSpace.abs()) 1261 if (fractional.abs() < remainingFreeSpace.abs())
1258 remainingFreeSpace = fractional; 1262 remainingFreeSpace = fractional;
1259 } 1263 }
1260 1264
1261 for (size_t i = 0; i < children.size(); ++i) { 1265 for (size_t i = 0; i < children.size(); ++i) {
1262 LayoutBox* child = children[i]; 1266 FlexItem& flexItem = children[i];
1267 LayoutBox* child = flexItem.box;
1263 if (child->isOutOfFlowPositioned()) { 1268 if (child->isOutOfFlowPositioned()) {
1264 childSizes.append(0);
1265 continue; 1269 continue;
1266 } 1270 }
1267 1271
1268 if (inflexibleItems.contains(child)) { 1272 if (flexItem.frozen)
1269 childSizes.append(inflexibleItems.get(child)); 1273 continue;
1270 } else { 1274 LayoutUnit childSize = flexItem.innerFlexBaseSize;
1271 LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild (*child); 1275 double extraSpace = 0;
1272 LayoutUnit childSize = childInnerFlexBaseSize; 1276 if (remainingFreeSpace > 0 && totalFlexGrow > 0 && flexSign == PositiveF lexibility && std::isfinite(totalFlexGrow)) {
1273 double extraSpace = 0; 1277 extraSpace = remainingFreeSpace * child->style()->flexGrow() / total FlexGrow;
1274 if (remainingFreeSpace > 0 && totalFlexGrow > 0 && flexSign == Posit iveFlexibility && std::isfinite(totalFlexGrow)) { 1278 } else if (remainingFreeSpace < 0 && totalWeightedFlexShrink > 0 && flex Sign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink) && child-> style()->flexShrink()) {
1275 extraSpace = remainingFreeSpace * child->style()->flexGrow() / t otalFlexGrow; 1279 extraSpace = remainingFreeSpace * child->style()->flexShrink() * fle xItem.innerFlexBaseSize / totalWeightedFlexShrink;
1276 } else if (remainingFreeSpace < 0 && totalWeightedFlexShrink > 0 && flexSign == NegativeFlexibility && std::isfinite(totalWeightedFlexShrink) && chi ld->style()->flexShrink()) { 1280 }
1277 extraSpace = remainingFreeSpace * child->style()->flexShrink() * childInnerFlexBaseSize / totalWeightedFlexShrink; 1281 if (std::isfinite(extraSpace))
1278 } 1282 childSize += LayoutUnit::fromFloatRound(extraSpace);
1279 if (std::isfinite(extraSpace))
1280 childSize += LayoutUnit::fromFloatRound(extraSpace);
1281 1283
1282 LayoutUnit adjustedChildSize = adjustChildSizeForMinAndMax(*child, c hildSize); 1284 LayoutUnit adjustedChildSize = adjustChildSizeForMinAndMax(*child, child Size);
1283 ASSERT(adjustedChildSize >= 0); 1285 DCHECK_GE(adjustedChildSize, 0);
1284 childSizes.append(adjustedChildSize); 1286 flexItem.flexedContentSize = adjustedChildSize;
1285 usedFreeSpace += adjustedChildSize - childInnerFlexBaseSize; 1287 usedFreeSpace += adjustedChildSize - flexItem.innerFlexBaseSize;
1286 1288
1287 LayoutUnit violation = adjustedChildSize - childSize; 1289 LayoutUnit violation = adjustedChildSize - childSize;
1288 if (violation > 0) 1290 if (violation > 0)
1289 minViolations.append(Violation(child, adjustedChildSize, childIn nerFlexBaseSize)); 1291 minViolations.append(&flexItem);
1290 else if (violation < 0) 1292 else if (violation < 0)
1291 maxViolations.append(Violation(child, adjustedChildSize, childIn nerFlexBaseSize)); 1293 maxViolations.append(&flexItem);
1292 totalViolation += violation; 1294 totalViolation += violation;
1293 }
1294 } 1295 }
1295 1296
1296 if (totalViolation) 1297 if (totalViolation)
1297 freezeViolations(totalViolation < 0 ? maxViolations : minViolations, rem ainingFreeSpace, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink, inflex ibleItems); 1298 freezeViolations(totalViolation < 0 ? maxViolations : minViolations, rem ainingFreeSpace, totalFlexGrow, totalFlexShrink, totalWeightedFlexShrink);
1298 else 1299 else
1299 remainingFreeSpace -= usedFreeSpace; 1300 remainingFreeSpace -= usedFreeSpace;
1300 1301
1301 return !totalViolation; 1302 return !totalViolation;
1302 } 1303 }
1303 1304
1304 static LayoutUnit initialJustifyContentOffset(LayoutUnit availableFreeSpace, Con tentPosition justifyContent, ContentDistributionType justifyContentDistribution, unsigned numberOfChildren) 1305 static LayoutUnit initialJustifyContentOffset(LayoutUnit availableFreeSpace, Con tentPosition justifyContent, ContentDistributionType justifyContentDistribution, unsigned numberOfChildren)
1305 { 1306 {
1306 if (justifyContent == ContentPositionFlexEnd) 1307 if (justifyContent == ContentPositionFlexEnd)
1307 return availableFreeSpace; 1308 return availableFreeSpace;
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 align = ItemPositionFlexStart; 1463 align = ItemPositionFlexStart;
1463 } 1464 }
1464 1465
1465 return align; 1466 return align;
1466 } 1467 }
1467 1468
1468 size_t LayoutFlexibleBox::numberOfInFlowPositionedChildren(const OrderedFlexItem List& children) const 1469 size_t LayoutFlexibleBox::numberOfInFlowPositionedChildren(const OrderedFlexItem List& children) const
1469 { 1470 {
1470 size_t count = 0; 1471 size_t count = 0;
1471 for (size_t i = 0; i < children.size(); ++i) { 1472 for (size_t i = 0; i < children.size(); ++i) {
1472 LayoutBox* child = children[i]; 1473 LayoutBox* child = children[i].box;
1473 if (!child->isOutOfFlowPositioned()) 1474 if (!child->isOutOfFlowPositioned())
1474 ++count; 1475 ++count;
1475 } 1476 }
1476 return count; 1477 return count;
1477 } 1478 }
1478 1479
1479 void LayoutFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis(LayoutBox& chil d) 1480 void LayoutFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis(LayoutBox& chil d)
1480 { 1481 {
1481 if (hasAutoMarginsInCrossAxis(child)) { 1482 if (hasAutoMarginsInCrossAxis(child)) {
1482 child.updateLogicalHeight(); 1483 child.updateLogicalHeight();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 return child.styleRef().overflowY(); 1533 return child.styleRef().overflowY();
1533 } 1534 }
1534 1535
1535 EOverflow LayoutFlexibleBox::crossAxisOverflowForChild(const LayoutBox& child) c onst 1536 EOverflow LayoutFlexibleBox::crossAxisOverflowForChild(const LayoutBox& child) c onst
1536 { 1537 {
1537 if (isHorizontalFlow()) 1538 if (isHorizontalFlow())
1538 return child.styleRef().overflowY(); 1539 return child.styleRef().overflowY();
1539 return child.styleRef().overflowX(); 1540 return child.styleRef().overflowX();
1540 } 1541 }
1541 1542
1542 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope , Vector<LineContext>& lineContexts) 1543 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, LayoutUnit availableFreeSpace, bool relayoutChi ldren, SubtreeLayoutScope& layoutScope, Vector<LineContext>& lineContexts)
1543 { 1544 {
1544 ASSERT(childSizes.size() == children.size());
1545
1546 ContentPosition position = styleRef().resolvedJustifyContentPosition(normalV alueBehavior()); 1545 ContentPosition position = styleRef().resolvedJustifyContentPosition(normalV alueBehavior());
1547 ContentDistributionType distribution = styleRef().resolvedJustifyContentDist ribution(normalValueBehavior()); 1546 ContentDistributionType distribution = styleRef().resolvedJustifyContentDist ribution(normalValueBehavior());
1548 1547
1549 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children); 1548 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children);
1550 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace); 1549 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace);
1551 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ; 1550 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ;
1552 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, position, distribution, numberOfChildrenForJustifyContent); 1551 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, position, distribution, numberOfChildrenForJustifyContent);
1553 if (style()->flexDirection() == FlowRowReverse && shouldPlaceBlockDirectionS crollbarOnLogicalLeft()) 1552 if (style()->flexDirection() == FlowRowReverse && shouldPlaceBlockDirectionS crollbarOnLogicalLeft())
1554 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight(); 1553 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight();
1555 1554
1556 LayoutUnit totalMainExtent = mainAxisExtent(); 1555 LayoutUnit totalMainExtent = mainAxisExtent();
1557 if (!shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) 1556 if (!shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1558 totalMainExtent -= isHorizontalFlow() ? verticalScrollbarWidth() : horiz ontalScrollbarHeight(); 1557 totalMainExtent -= isHorizontalFlow() ? verticalScrollbarWidth() : horiz ontalScrollbarHeight();
1559 LayoutUnit maxAscent, maxDescent; // Used when align-items: baseline. 1558 LayoutUnit maxAscent, maxDescent; // Used when align-items: baseline.
1560 LayoutUnit maxChildCrossAxisExtent; 1559 LayoutUnit maxChildCrossAxisExtent;
1561 size_t seenInFlowPositionedChildren = 0; 1560 size_t seenInFlowPositionedChildren = 0;
1562 bool shouldFlipMainAxis = !isColumnFlow() && !isLeftToRightFlow(); 1561 bool shouldFlipMainAxis = !isColumnFlow() && !isLeftToRightFlow();
1563 for (size_t i = 0; i < children.size(); ++i) { 1562 for (size_t i = 0; i < children.size(); ++i) {
1564 LayoutBox* child = children[i]; 1563 const FlexItem& flexItem = children[i];
1564 LayoutBox* child = flexItem.box;
1565 1565
1566 if (child->isOutOfFlowPositioned()) { 1566 if (child->isOutOfFlowPositioned()) {
1567 prepareChildForPositionedLayout(*child); 1567 prepareChildForPositionedLayout(*child);
1568 continue; 1568 continue;
1569 } 1569 }
1570 1570
1571 child->setMayNeedPaintInvalidation(); 1571 child->setMayNeedPaintInvalidation();
1572 1572
1573 LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPadding ExtentForChild(*child); 1573 LayoutUnit childPreferredSize = flexItem.flexedContentSize + mainAxisBor derAndPaddingExtentForChild(*child);
1574 setOverrideMainAxisSizeForChild(*child, childPreferredSize); 1574 setOverrideMainAxisSizeForChild(*child, childPreferredSize);
1575 if (childPreferredSize != mainAxisExtentForChild(*child)) { 1575 if (childPreferredSize != mainAxisExtentForChild(*child)) {
1576 child->setChildNeedsLayout(MarkOnlyThis); 1576 child->setChildNeedsLayout(MarkOnlyThis);
1577 } else { 1577 } else {
1578 // To avoid double applying margin changes in updateAutoMarginsInCro ssAxis, we reset the margins here. 1578 // To avoid double applying margin changes in updateAutoMarginsInCro ssAxis, we reset the margins here.
1579 resetAutoMarginsAndLogicalTopInCrossAxis(*child); 1579 resetAutoMarginsAndLogicalTopInCrossAxis(*child);
1580 } 1580 }
1581 // We may have already forced relayout for orthogonal flowing children i n computeInnerFlexBaseSizeForChild. 1581 // We may have already forced relayout for orthogonal flowing children i n computeInnerFlexBaseSizeForChild.
1582 bool forceChildRelayout = relayoutChildren && !childFlexBaseSizeRequires Layout(*child); 1582 bool forceChildRelayout = relayoutChildren && !childFlexBaseSizeRequires Layout(*child);
1583 if (child->isLayoutBlock() && toLayoutBlock(*child).hasPercentHeightDesc endants() && m_relaidOutChildren.contains(child)) { 1583 if (child->isLayoutBlock() && toLayoutBlock(*child).hasPercentHeightDesc endants() && m_relaidOutChildren.contains(child)) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 // This is similar to the logic in layoutAndPlaceChildren, except we place t he children 1651 // This is similar to the logic in layoutAndPlaceChildren, except we place t he children
1652 // starting from the end of the flexbox. We also don't need to layout anythi ng since we're 1652 // starting from the end of the flexbox. We also don't need to layout anythi ng since we're
1653 // just moving the children to a new position. 1653 // just moving the children to a new position.
1654 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children); 1654 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children);
1655 LayoutUnit mainAxisOffset = logicalHeight() - flowAwareBorderEnd() - flowAwa rePaddingEnd(); 1655 LayoutUnit mainAxisOffset = logicalHeight() - flowAwareBorderEnd() - flowAwa rePaddingEnd();
1656 mainAxisOffset -= initialJustifyContentOffset(availableFreeSpace, position, distribution, numberOfChildrenForJustifyContent); 1656 mainAxisOffset -= initialJustifyContentOffset(availableFreeSpace, position, distribution, numberOfChildrenForJustifyContent);
1657 mainAxisOffset -= isHorizontalFlow() ? verticalScrollbarWidth() : horizontal ScrollbarHeight(); 1657 mainAxisOffset -= isHorizontalFlow() ? verticalScrollbarWidth() : horizontal ScrollbarHeight();
1658 1658
1659 size_t seenInFlowPositionedChildren = 0; 1659 size_t seenInFlowPositionedChildren = 0;
1660 for (size_t i = 0; i < children.size(); ++i) { 1660 for (size_t i = 0; i < children.size(); ++i) {
1661 LayoutBox* child = children[i]; 1661 LayoutBox* child = children[i].box;
1662 1662
1663 if (child->isOutOfFlowPositioned()) 1663 if (child->isOutOfFlowPositioned())
1664 continue; 1664 continue;
1665 1665
1666 mainAxisOffset -= mainAxisExtentForChild(*child) + flowAwareMarginEndFor Child(*child); 1666 mainAxisOffset -= mainAxisExtentForChild(*child) + flowAwareMarginEndFor Child(*child);
1667 1667
1668 setFlowAwareLocationForChild(*child, LayoutPoint(mainAxisOffset, crossAx isOffset + flowAwareMarginBeforeForChild(*child))); 1668 setFlowAwareLocationForChild(*child, LayoutPoint(mainAxisOffset, crossAx isOffset + flowAwareMarginBeforeForChild(*child)));
1669 1669
1670 mainAxisOffset -= flowAwareMarginStartForChild(*child); 1670 mainAxisOffset -= flowAwareMarginStartForChild(*child);
1671 1671
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 ASSERT(child); 1861 ASSERT(child);
1862 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; 1862 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent;
1863 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; 1863 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge;
1864 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; 1864 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent;
1865 adjustAlignmentForChild(*child, newOffset - originalOffset); 1865 adjustAlignmentForChild(*child, newOffset - originalOffset);
1866 } 1866 }
1867 } 1867 }
1868 } 1868 }
1869 1869
1870 } // namespace blink 1870 } // 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