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 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 if (isColumnFlow()) | 347 if (isColumnFlow()) |
348 return style()->writingMode() == TopToBottomWritingMode || style()->writ
ingMode() == LeftToRightWritingMode; | 348 return style()->writingMode() == TopToBottomWritingMode || style()->writ
ingMode() == LeftToRightWritingMode; |
349 return style()->isLeftToRightDirection() ^ (style()->flexDirection() == Flow
RowReverse); | 349 return style()->isLeftToRightDirection() ^ (style()->flexDirection() == Flow
RowReverse); |
350 } | 350 } |
351 | 351 |
352 bool LayoutFlexibleBox::isMultiline() const | 352 bool LayoutFlexibleBox::isMultiline() const |
353 { | 353 { |
354 return style()->flexWrap() != FlexNoWrap; | 354 return style()->flexWrap() != FlexNoWrap; |
355 } | 355 } |
356 | 356 |
357 Length LayoutFlexibleBox::flexBasisForChild(LayoutBox& child) const | 357 Length LayoutFlexibleBox::flexBasisForChild(const LayoutBox& child) const |
358 { | 358 { |
359 Length flexLength = child.style()->flexBasis(); | 359 Length flexLength = child.style()->flexBasis(); |
360 if (flexLength.isAuto()) | 360 if (flexLength.isAuto()) |
361 flexLength = isHorizontalFlow() ? child.style()->width() : child.style()
->height(); | 361 flexLength = isHorizontalFlow() ? child.style()->width() : child.style()
->height(); |
362 return flexLength; | 362 return flexLength; |
363 } | 363 } |
364 | 364 |
365 LayoutUnit LayoutFlexibleBox::crossAxisExtentForChild(LayoutBox& child) const | 365 LayoutUnit LayoutFlexibleBox::crossAxisExtentForChild(LayoutBox& child) const |
366 { | 366 { |
367 return isHorizontalFlow() ? child.size().height() : child.size().width(); | 367 return isHorizontalFlow() ? child.size().height() : child.size().width(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 | 428 |
429 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(LayoutBox& child, Si
zeType sizeType, const Length& size) | 429 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(LayoutBox& child, Si
zeType sizeType, const Length& size) |
430 { | 430 { |
431 // If we have a horizontal flow, that means the main size is the width. | 431 // If we have a horizontal flow, that means the main size is the width. |
432 // That's the logical width for horizontal writing modes, and the logical he
ight in vertical writing modes. | 432 // That's the logical width for horizontal writing modes, and the logical he
ight in vertical writing modes. |
433 // For a vertical flow, main size is the height, so it's the inverse. | 433 // For a vertical flow, main size is the height, so it's the inverse. |
434 // So we need the logical width if we have a horizontal flow and horizontal
writing mode, or vertical flow and vertical writing mode. | 434 // So we need the logical width if we have a horizontal flow and horizontal
writing mode, or vertical flow and vertical writing mode. |
435 // Otherwise we need the logical height. | 435 // Otherwise we need the logical height. |
436 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) { | 436 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) { |
437 // We don't have to check for "auto" here - computeContentLogicalHeight
will just return -1 for that case anyway. | 437 // We don't have to check for "auto" here - computeContentLogicalHeight
will just return -1 for that case anyway. |
438 if (size.isIntrinsic()) | 438 // It's safe to access scrollbarLogicalHeight here because computeNextFl
exLine will have already |
439 child.layoutIfNeeded(); | 439 // forced layout on the child. |
440 return child.computeContentLogicalHeight(sizeType, size, child.logicalHe
ight() - child.borderAndPaddingLogicalHeight()) + child.scrollbarLogicalHeight()
; | 440 return child.computeContentLogicalHeight(sizeType, size, child.logicalHe
ight() - child.borderAndPaddingLogicalHeight()) + child.scrollbarLogicalHeight()
; |
441 } | 441 } |
442 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(),
this) - child.borderAndPaddingLogicalWidth(); | 442 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(),
this) - child.borderAndPaddingLogicalWidth(); |
443 } | 443 } |
444 | 444 |
445 WritingMode LayoutFlexibleBox::transformedWritingMode() const | 445 WritingMode LayoutFlexibleBox::transformedWritingMode() const |
446 { | 446 { |
447 WritingMode mode = style()->writingMode(); | 447 WritingMode mode = style()->writingMode(); |
448 if (!isColumnFlow()) | 448 if (!isColumnFlow()) |
449 return mode; | 449 return mode; |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 if (flexBasis.hasPercent()) { | 622 if (flexBasis.hasPercent()) { |
623 return isColumnFlow() ? | 623 return isColumnFlow() ? |
624 child.computePercentageLogicalHeight(flexBasis) != -1 : | 624 child.computePercentageLogicalHeight(flexBasis) != -1 : |
625 hasDefiniteLogicalWidth(); | 625 hasDefiniteLogicalWidth(); |
626 } | 626 } |
627 return true; | 627 return true; |
628 } | 628 } |
629 | 629 |
630 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(LayoutBox& child) const | 630 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(LayoutBox& child) const |
631 { | 631 { |
632 return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && hasOrth
ogonalFlow(child); | 632 return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && ( |
| 633 hasOrthogonalFlow(child) || crossAxisOverflowForChild(child) == OAUTO); |
633 } | 634 } |
634 | 635 |
635 LayoutUnit LayoutFlexibleBox::computeInnerFlexBaseSizeForChild(LayoutBox& child,
ChildLayoutType childLayoutType) | 636 LayoutUnit LayoutFlexibleBox::computeInnerFlexBaseSizeForChild(LayoutBox& child,
ChildLayoutType childLayoutType) |
636 { | 637 { |
637 child.clearOverrideSize(); | 638 child.clearOverrideSize(); |
638 | 639 |
639 if (child.isImage() || child.isVideo() || child.isCanvas()) | 640 if (child.isImage() || child.isVideo() || child.isCanvas()) |
640 UseCounter::count(document(), UseCounter::AspectRatioFlexItem); | 641 UseCounter::count(document(), UseCounter::AspectRatioFlexItem); |
641 | 642 |
642 Length flexBasis = flexBasisForChild(child); | 643 Length flexBasis = flexBasisForChild(child); |
643 if (!mainAxisLengthIsDefinite(child, flexBasis)) { | 644 if (!mainAxisLengthIsDefinite(child, flexBasis)) { |
644 LayoutUnit mainAxisExtent; | 645 LayoutUnit mainAxisExtent; |
645 if (hasOrthogonalFlow(child)) { | 646 if (childFlexBaseSizeRequiresLayout(child)) { |
646 if (childLayoutType == NeverLayout) | 647 if (childLayoutType == NeverLayout) |
647 return LayoutUnit(); | 648 return LayoutUnit(); |
648 | 649 |
649 if (child.needsLayout() || childLayoutType == ForceLayout || !m_intr
insicSizeAlongMainAxis.contains(&child)) { | 650 if (child.needsLayout() || childLayoutType == ForceLayout || !m_intr
insicSizeAlongMainAxis.contains(&child)) { |
650 m_intrinsicSizeAlongMainAxis.remove(&child); | 651 m_intrinsicSizeAlongMainAxis.remove(&child); |
651 child.forceChildLayout(); | 652 child.forceChildLayout(); |
652 m_intrinsicSizeAlongMainAxis.set(&child, child.logicalHeight()); | 653 m_intrinsicSizeAlongMainAxis.set(&child, hasOrthogonalFlow(child
) ? child.logicalHeight() : child.logicalWidth()); |
653 } | 654 } |
654 mainAxisExtent = m_intrinsicSizeAlongMainAxis.get(&child); | 655 mainAxisExtent = m_intrinsicSizeAlongMainAxis.get(&child); |
655 } else { | 656 } else { |
656 mainAxisExtent = child.maxPreferredLogicalWidth(); | 657 mainAxisExtent = child.maxPreferredLogicalWidth(); |
657 } | 658 } |
658 ASSERT(mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child) >=
0); | 659 ASSERT(mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child) >=
0); |
659 return mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child); | 660 return mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child); |
660 } | 661 } |
661 return std::max(LayoutUnit(), computeMainAxisExtentForChild(child, MainOrPre
ferredSize, flexBasis)); | 662 return std::max(LayoutUnit(), computeMainAxisExtentForChild(child, MainOrPre
ferredSize, flexBasis)); |
662 } | 663 } |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); | 916 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); |
916 | 917 |
917 bool lineHasInFlowItem = false; | 918 bool lineHasInFlowItem = false; |
918 | 919 |
919 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord
erIterator.next()) { | 920 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord
erIterator.next()) { |
920 if (child->isOutOfFlowPositioned()) { | 921 if (child->isOutOfFlowPositioned()) { |
921 orderedChildren.append(child); | 922 orderedChildren.append(child); |
922 continue; | 923 continue; |
923 } | 924 } |
924 | 925 |
| 926 // If this condition is true, then computeMainAxisExtentForChild will ca
ll child.contentLogicalHeight() |
| 927 // and child.scrollbarLogicalHeight(), so if the child has intrinsic min
/max/preferred size, |
| 928 // run layout on it now to make sure its logical height and scroll bars
are up-to-date. |
| 929 if (childHasIntrinsicMainAxisSize(*child)) |
| 930 child->layoutIfNeeded(); |
| 931 |
925 LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(*ch
ild, relayoutChildren ? ForceLayout : LayoutIfNeeded); | 932 LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(*ch
ild, relayoutChildren ? ForceLayout : LayoutIfNeeded); |
926 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx
tentForChild(*child) | 933 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx
tentForChild(*child) |
927 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight()
); | 934 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight()
); |
928 LayoutUnit childOuterFlexBaseSize = childInnerFlexBaseSize + childMainAx
isMarginBorderPadding; | 935 LayoutUnit childOuterFlexBaseSize = childInnerFlexBaseSize + childMainAx
isMarginBorderPadding; |
929 | 936 |
930 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa
x(*child, childInnerFlexBaseSize); | 937 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa
x(*child, childInnerFlexBaseSize); |
931 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent
+ childMainAxisMarginBorderPadding; | 938 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent
+ childMainAxisMarginBorderPadding; |
932 | 939 |
933 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize
> lineBreakLength && lineHasInFlowItem) | 940 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize
> lineBreakLength && lineHasInFlowItem) |
934 break; | 941 break; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 // "stretch" themselves in their inline axis, i.e. a <div> has an implicit w
idth: 100%. | 1119 // "stretch" themselves in their inline axis, i.e. a <div> has an implicit w
idth: 100%. |
1113 // Therefore, we never need to stretch an item if we're a vertical flow, bec
ause the child | 1120 // Therefore, we never need to stretch an item if we're a vertical flow, bec
ause the child |
1114 // will automatically stretch itself. | 1121 // will automatically stretch itself. |
1115 // TODO(cbiesinger): this code is wrong when the child has an orthogonal flo
w and we're vertical. crbug.com/482766 | 1122 // TODO(cbiesinger): this code is wrong when the child has an orthogonal flo
w and we're vertical. crbug.com/482766 |
1116 if (alignmentForChild(child) != ItemPositionStretch) | 1123 if (alignmentForChild(child) != ItemPositionStretch) |
1117 return false; | 1124 return false; |
1118 | 1125 |
1119 return isHorizontalFlow() && child.style()->height().isAuto(); | 1126 return isHorizontalFlow() && child.style()->height().isAuto(); |
1120 } | 1127 } |
1121 | 1128 |
| 1129 bool LayoutFlexibleBox::childHasIntrinsicMainAxisSize(const LayoutBox& child) co
nst |
| 1130 { |
| 1131 bool result = false; |
| 1132 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) { |
| 1133 Length childFlexBasis = flexBasisForChild(child); |
| 1134 Length childMinSize = isHorizontalFlow() ? child.style()->minWidth() : c
hild.style()->minHeight(); |
| 1135 Length childMaxSize = isHorizontalFlow() ? child.style()->maxWidth() : c
hild.style()->maxHeight(); |
| 1136 if (childFlexBasis.isIntrinsic() || childMinSize.isIntrinsic() || childM
axSize.isIntrinsic()) |
| 1137 result = true; |
| 1138 } |
| 1139 return result; |
| 1140 } |
| 1141 |
1122 EOverflow LayoutFlexibleBox::mainAxisOverflowForChild(LayoutBox& child) const | 1142 EOverflow LayoutFlexibleBox::mainAxisOverflowForChild(LayoutBox& child) const |
1123 { | 1143 { |
1124 if (isHorizontalFlow()) | 1144 if (isHorizontalFlow()) |
1125 return child.styleRef().overflowX(); | 1145 return child.styleRef().overflowX(); |
1126 return child.styleRef().overflowY(); | 1146 return child.styleRef().overflowY(); |
1127 } | 1147 } |
1128 | 1148 |
| 1149 EOverflow LayoutFlexibleBox::crossAxisOverflowForChild(LayoutBox& child) const |
| 1150 { |
| 1151 if (isHorizontalFlow()) |
| 1152 return child.styleRef().overflowY(); |
| 1153 return child.styleRef().overflowX(); |
| 1154 } |
1129 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons
t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou
tUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope
, Vector<LineContext>& lineContexts) | 1155 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons
t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou
tUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope
, Vector<LineContext>& lineContexts) |
1130 { | 1156 { |
1131 ASSERT(childSizes.size() == children.size()); | 1157 ASSERT(childSizes.size() == children.size()); |
1132 | 1158 |
1133 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren(
children); | 1159 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren(
children); |
1134 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available
FreeSpace); | 1160 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available
FreeSpace); |
1135 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart()
; | 1161 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart()
; |
1136 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j
ustifyContentPosition(), style()->justifyContentDistribution(), numberOfChildren
ForJustifyContent); | 1162 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j
ustifyContentPosition(), style()->justifyContentDistribution(), numberOfChildren
ForJustifyContent); |
1137 if (style()->flexDirection() == FlowRowReverse) | 1163 if (style()->flexDirection() == FlowRowReverse) |
1138 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo
ntalScrollbarHeight(); | 1164 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo
ntalScrollbarHeight(); |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 ASSERT(child); | 1496 ASSERT(child); |
1471 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE
xtent; | 1497 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE
xtent; |
1472 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset
- crossAxisStartEdge; | 1498 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset
- crossAxisStartEdge; |
1473 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi
sExtent; | 1499 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi
sExtent; |
1474 adjustAlignmentForChild(*child, newOffset - originalOffset); | 1500 adjustAlignmentForChild(*child, newOffset - originalOffset); |
1475 } | 1501 } |
1476 } | 1502 } |
1477 } | 1503 } |
1478 | 1504 |
1479 } | 1505 } |
OLD | NEW |