Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp (111634 => 111635)
--- trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp 2012-03-22 01:13:56 UTC (rev 111634)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp 2012-03-22 01:29:04 UTC (rev 111635)
@@ -102,38 +102,19 @@
Vector<int>::const_iterator m_orderValuesIterator;
};
-struct RenderFlexibleBox::WrapReverseContext {
- explicit WrapReverseContext(EFlexWrap flexWrap)
- : isWrapReverse(flexWrap == FlexWrapReverse)
+struct RenderFlexibleBox::LineContext {
+ LineContext(LayoutUnit crossAxisOffset, LayoutUnit crossAxisExtent, size_t numberOfChildren, LayoutUnit maxAscent)
+ : crossAxisOffset(crossAxisOffset)
+ , crossAxisExtent(crossAxisExtent)
+ , numberOfChildren(numberOfChildren)
+ , maxAscent(maxAscent)
{
}
- void addCrossAxisOffset(LayoutUnit offset)
- {
- if (!isWrapReverse)
- return;
- crossAxisOffsets.append(offset);
- }
-
- void addNumberOfChildrenOnLine(size_t numberOfChildren)
- {
- if (!isWrapReverse)
- return;
- childrenPerLine.append(numberOfChildren);
- }
-
- LayoutUnit lineCrossAxisDelta(size_t line, LayoutUnit crossAxisContentExtent) const
- {
- ASSERT(line + 1 < crossAxisOffsets.size());
- LayoutUnit lineHeight = crossAxisOffsets[line + 1] - crossAxisOffsets[line];
- LayoutUnit originalOffset = crossAxisOffsets[line] - crossAxisOffsets[0];
- LayoutUnit newOffset = crossAxisContentExtent - originalOffset - lineHeight;
- return newOffset - originalOffset;
- }
-
- WTF::Vector<LayoutUnit> crossAxisOffsets;
- WTF::Vector<size_t> childrenPerLine;
- bool isWrapReverse;
+ LayoutUnit crossAxisOffset;
+ LayoutUnit crossAxisExtent;
+ size_t numberOfChildren;
+ LayoutUnit maxAscent;
};
@@ -607,12 +588,9 @@
float totalPositiveFlexibility;
float totalNegativeFlexibility;
LayoutUnit minMaxAppliedMainAxisExtent;
+ WTF::Vector<LineContext> lineContexts;
FlexOrderIterator flexIterator(this, flexOrderValues);
- // For wrap-reverse, we need to layout as wrap, then reverse the lines. The next two arrays
- // are some extra information so it's possible to reverse the lines.
- WrapReverseContext wrapReverseContext(style()->flexWrap());
-
LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
while (computeNextFlexLine(flexIterator, orderedChildren, preferredMainAxisExtent, totalPositiveFlexibility, totalNegativeFlexibility, minMaxAppliedMainAxisExtent)) {
LayoutUnit availableFreeSpace = computeAvailableFreeSpace(preferredMainAxisExtent);
@@ -624,16 +602,15 @@
ASSERT(inflexibleItems.size() > 0);
}
- wrapReverseContext.addNumberOfChildrenOnLine(orderedChildren.size());
- wrapReverseContext.addCrossAxisOffset(crossAxisOffset);
- layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace);
+ layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace, lineContexts);
}
- if (wrapReverseContext.isWrapReverse) {
- wrapReverseContext.addCrossAxisOffset(crossAxisOffset);
- flipForWrapReverse(flexIterator, wrapReverseContext);
- }
+ ASSERT(!lineContexts.size());
+ alignChildren(flexIterator, lineContexts);
+ if (style()->flexWrap() == FlexWrapReverse)
+ flipForWrapReverse(flexIterator, lineContexts);
+
// direction:rtl + flex-direction:column means the cross-axis direction is flipped.
flipForRightToLeftColumn(flexIterator);
}
@@ -868,7 +845,7 @@
return align;
}
-void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace)
+void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>& lineContexts)
{
LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart();
mainAxisOffset += initialPackingOffset(availableFreeSpace, style()->flexPack(), childSizes.size());
@@ -930,8 +907,7 @@
}
LayoutUnit lineCrossAxisExtent = isMultiline() ? maxChildCrossAxisExtent : crossAxisContentExtent();
- alignChildren(children, lineCrossAxisExtent, maxAscent);
-
+ lineContexts.append(LineContext(crossAxisOffset, lineCrossAxisExtent, children.size(), maxAscent));
crossAxisOffset += lineCrossAxisExtent;
}
@@ -976,49 +952,61 @@
child->repaintDuringLayoutIfMoved(oldRect);
}
-void RenderFlexibleBox::alignChildren(const OrderedFlexItemList& children, LayoutUnit lineCrossAxisExtent, LayoutUnit maxAscent)
+void RenderFlexibleBox::alignChildren(FlexOrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts)
{
- LayoutUnit minMarginAfterBaseline = std::numeric_limits<LayoutUnit>::max();
+ // Keep track of the space between the baseline edge and the after edge of the box for each line.
+ WTF::Vector<LayoutUnit> minMarginAfterBaselines;
- for (size_t i = 0; i < children.size(); ++i) {
- RenderBox* child = children[i];
- switch (flexAlignForChild(child)) {
- case AlignAuto:
- ASSERT_NOT_REACHED();
- break;
- case AlignStretch: {
- applyStretchAlignmentToChild(child, lineCrossAxisExtent);
- // Since wrap-reverse flips cross start and cross end, strech children should be aligned with the cross end.
- if (style()->flexWrap() == FlexWrapReverse)
+ RenderBox* child = iterator.first();
+ for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
+ LayoutUnit minMarginAfterBaseline = std::numeric_limits<LayoutUnit>::max();
+ LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisExtent;
+ LayoutUnit maxAscent = lineContexts[lineNumber].maxAscent;
+
+ for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) {
+ switch (flexAlignForChild(child)) {
+ case AlignAuto:
+ ASSERT_NOT_REACHED();
+ break;
+ case AlignStretch: {
+ applyStretchAlignmentToChild(child, lineCrossAxisExtent);
+ // Since wrap-reverse flips cross start and cross end, strech children should be aligned with the cross end.
+ if (style()->flexWrap() == FlexWrapReverse)
+ adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
+ break;
+ }
+ case AlignStart:
+ break;
+ case AlignEnd:
adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
- break;
- }
- case AlignStart:
- break;
- case AlignEnd:
- adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
- break;
- case AlignCenter:
- adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) / 2);
- break;
- case AlignBaseline: {
- LayoutUnit ascent = marginBoxAscentForChild(child);
- LayoutUnit startOffset = maxAscent - ascent;
- adjustAlignmentForChild(child, startOffset);
+ break;
+ case AlignCenter:
+ adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) / 2);
+ break;
+ case AlignBaseline: {
+ LayoutUnit ascent = marginBoxAscentForChild(child);
+ LayoutUnit startOffset = maxAscent - ascent;
+ adjustAlignmentForChild(child, startOffset);
- if (style()->flexWrap() == FlexWrapReverse)
- minMarginAfterBaseline = std::min(minMarginAfterBaseline, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) - startOffset);
- break;
+ if (style()->flexWrap() == FlexWrapReverse)
+ minMarginAfterBaseline = std::min(minMarginAfterBaseline, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) - startOffset);
+ break;
+ }
+ }
}
- }
+ minMarginAfterBaselines.append(minMarginAfterBaseline);
}
+ if (style()->flexWrap() != FlexWrapReverse)
+ return;
+
// wrap-reverse flips the cross axis start and end. For baseline alignment, this means we
// need to align the after edge of baseline elements with the after edge of the flex line.
- if (style()->flexWrap() == FlexWrapReverse && minMarginAfterBaseline) {
- for (size_t i = 0; i < children.size(); ++i) {
- RenderBox* child = children[i];
- if (flexAlignForChild(child) == AlignBaseline)
+ child = iterator.first();
+ for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
+ LayoutUnit minMarginAfterBaseline = minMarginAfterBaselines[lineNumber];
+ for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) {
+ if (flexAlignForChild(child) == AlignBaseline && minMarginAfterBaseline)
adjustAlignmentForChild(child, minMarginAfterBaseline);
}
}
@@ -1063,26 +1051,25 @@
}
}
-void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WrapReverseContext& wrapReverseContext)
+void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts)
{
if (!isColumnFlow())
computeLogicalHeight();
- size_t currentChild = 0;
- size_t lineNumber = 0;
LayoutUnit contentExtent = crossAxisContentExtent();
- for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
- LayoutPoint location = flowAwareLocationForChild(child);
- location.setY(location.y() + wrapReverseContext.lineCrossAxisDelta(lineNumber, contentExtent));
+ RenderBox* child = iterator.first();
+ for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
+ for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) {
+ LayoutPoint location = flowAwareLocationForChild(child);
+ LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisExtent;
+ LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - lineContexts[0].crossAxisOffset;
+ LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxisExtent;
+ location.setY(location.y() + newOffset - originalOffset);
- LayoutRect oldRect = child->frameRect();
- setFlowAwareLocationForChild(child, location);
- if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
- child->repaintDuringLayoutIfMoved(oldRect);
-
- if (++currentChild == wrapReverseContext.childrenPerLine[lineNumber]) {
- ++lineNumber;
- currentChild = 0;
+ LayoutRect oldRect = child->frameRect();
+ setFlowAwareLocationForChild(child, location);
+ if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
+ child->repaintDuringLayoutIfMoved(oldRect);
}
}
}
Modified: trunk/Source/WebCore/rendering/RenderFlexibleBox.h (111634 => 111635)
--- trunk/Source/WebCore/rendering/RenderFlexibleBox.h 2012-03-22 01:13:56 UTC (rev 111634)
+++ trunk/Source/WebCore/rendering/RenderFlexibleBox.h 2012-03-22 01:29:04 UTC (rev 111635)
@@ -61,7 +61,7 @@
typedef WTF::HashMap<const RenderBox*, LayoutUnit> InflexibleFlexItemSize;
typedef WTF::Vector<RenderBox*> OrderedFlexItemList;
- struct WrapReverseContext;
+ struct LineContext;
bool hasOrthogonalFlow(RenderBox* child) const;
bool isColumnFlow() const;
@@ -114,12 +114,12 @@
bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset);
- void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace);
+ void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>& lineContexts);
void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
- void alignChildren(const OrderedFlexItemList&, LayoutUnit lineCrossAxisExtent, LayoutUnit maxAscent);
+ void alignChildren(FlexOrderIterator&, const WTF::Vector<LineContext>&);
void applyStretchAlignmentToChild(RenderBox*, LayoutUnit lineCrossAxisExtent);
void flipForRightToLeftColumn(FlexOrderIterator&);
- void flipForWrapReverse(FlexOrderIterator&, const WrapReverseContext&);
+ void flipForWrapReverse(FlexOrderIterator&, const WTF::Vector<LineContext>&);
};
} // namespace WebCore