OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |