Changeset 93651 in webkit
- Timestamp:
- Aug 23, 2011 4:10:45 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r93650 r93651 1 2011-08-23 Tony Chang <tony@chromium.org> 2 3 Add handling of mix-width and max-width for flexitems 4 https://bugs.webkit.org/show_bug.cgi?id=66723 5 6 Reviewed by David Hyatt. 7 8 * css3/flexbox/003-expected.txt: Added. 9 * css3/flexbox/003.html: Added. 10 1 11 2011-08-23 Adam Barth <abarth@webkit.org> 2 12 -
trunk/Source/WebCore/ChangeLog
r93648 r93651 1 2011-08-23 Tony Chang <tony@chromium.org> 2 3 Add handling of mix-width and max-width for flexitems 4 https://bugs.webkit.org/show_bug.cgi?id=66723 5 6 Reviewed by David Hyatt. 7 8 If we flex past a min/max width value, we need to mark the flexitem as 9 a fixed width and re-start the flexing algorithm. We use a HashMap to 10 keep track of fixed width items. 11 12 This patch also split out the size computation from the actual layout 13 to avoid unnecessary layouts caused by restarting the flexing algorithm. 14 15 Test: css3/flexbox/003.html 16 17 * rendering/RenderFlexibleBox.cpp: 18 (WebCore::RenderFlexibleBox::layoutHorizontalBlock): 19 (WebCore::RenderFlexibleBox::runFreeSpaceAllocationAlgorithm): 20 * rendering/RenderFlexibleBox.h: 21 1 22 2011-08-23 Pratik Solanki <psolanki@apple.com> 2 23 -
trunk/Source/WebCore/rendering/RenderFlexibleBox.cpp
r93547 r93651 100 100 m_overflow.clear(); 101 101 102 // FIXME: Assume horizontal layout until flex- directionis added.102 // FIXME: Assume horizontal layout until flex-flow is added. 103 103 layoutHorizontalBlock(relayoutChildren); 104 104 … … 117 117 static LayoutUnit preferredFlexItemContentWidth(RenderBox* child) 118 118 { 119 // FIXME: Handle vertical writing modes with horizontal flexing. 119 120 if (child->style()->width().isAuto()) 120 121 return child->maxPreferredLogicalWidth() - child->borderLeft() - child->borderRight() - child->verticalScrollbarWidth() - child->paddingLeft() - child->paddingRight(); … … 129 130 FlexibleBoxIterator iterator(this); 130 131 131 computePreferredSize (relayoutChildren, iterator, preferredSize, totalPositiveFlexibility, totalNegativeFlexibility);132 computePreferredSizeHorizontal(relayoutChildren, iterator, preferredSize, totalPositiveFlexibility, totalNegativeFlexibility); 132 133 LayoutUnit availableFreeSpace = contentWidth() - preferredSize; 133 134 134 LayoutUnit xOffset = borderLeft() + paddingLeft(); 135 LayoutUnit yOffset = borderTop() + paddingTop(); 136 for (RenderBox* child = iterator.first(); child; child = iterator.next()) { 137 LayoutUnit childPreferredSize = preferredFlexItemContentWidth(child); 138 // FIXME: Handle max-width and min-width (we should clamp to the max/min value and restart the algorithm). 139 if (availableFreeSpace > 0 && totalPositiveFlexibility > 0) 140 childPreferredSize += lroundf(availableFreeSpace * child->style()->flexboxWidthPositiveFlex() / totalPositiveFlexibility); 141 else if (availableFreeSpace < 0 && totalNegativeFlexibility > 0) 142 childPreferredSize += lroundf(availableFreeSpace * child->style()->flexboxWidthNegativeFlex() / totalNegativeFlexibility); 143 144 childPreferredSize += child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight(); 145 child->setOverrideSize(LayoutSize(childPreferredSize, 0)); 146 child->setChildNeedsLayout(true); 147 child->layoutIfNeeded(); 148 149 setHeight(std::max(height(), borderTop() + paddingTop() + child->marginTop() + child->height() + child->marginBottom() + paddingBottom() + borderBottom() + horizontalScrollbarHeight())); 150 151 if (child->style()->marginLeft().isAuto()) 152 child->setMarginLeft(availableFreeSpace > 0 ? lroundf(availableFreeSpace / totalPositiveFlexibility) : 0); 153 if (child->style()->marginRight().isAuto()) 154 child->setMarginRight(availableFreeSpace > 0 ? lroundf(availableFreeSpace / totalPositiveFlexibility) : 0); 155 156 xOffset += child->marginLeft(); 157 child->setLocation(IntPoint(xOffset, yOffset)); 158 xOffset += child->width() + child->marginRight(); 135 InflexibleFlexItemSize inflexibleItems; 136 while (!runFreeSpaceAllocationAlgorithmHorizontal(availableFreeSpace, totalPositiveFlexibility, totalNegativeFlexibility, inflexibleItems)) { 137 ASSERT(totalPositiveFlexibility >= 0 && totalNegativeFlexibility >= 0); 138 ASSERT(inflexibleItems.size() > 0); 159 139 } 160 140 … … 168 148 } 169 149 170 void RenderFlexibleBox::computePreferredSize (bool relayoutChildren, FlexibleBoxIterator& iterator, LayoutUnit& preferredSize, float& totalPositiveFlexibility, float& totalNegativeFlexibility)150 void RenderFlexibleBox::computePreferredSizeHorizontal(bool relayoutChildren, FlexibleBoxIterator& iterator, LayoutUnit& preferredSize, float& totalPositiveFlexibility, float& totalNegativeFlexibility) 171 151 { 172 152 preferredSize = 0; 173 153 totalPositiveFlexibility = totalNegativeFlexibility = 0; 174 154 155 // FIXME: Handle vertical writing modes with horizontal flexing. 175 156 LayoutUnit flexboxAvailableLogicalWidth = availableLogicalWidth(); 176 157 for (RenderBox* child = iterator.first(); child; child = iterator.next()) { … … 201 182 } 202 183 184 // Returns true if we successfully ran the algorithm and sized the flex items. 185 bool RenderFlexibleBox::runFreeSpaceAllocationAlgorithmHorizontal(LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize& inflexibleItems) 186 { 187 FlexibleBoxIterator iterator(this); 188 189 // FIXME: Handle vertical writing modes with horizontal flexing. 190 LayoutUnit flexboxAvailableLogicalWidth = availableLogicalWidth(); 191 WTF::Vector<LayoutUnit> childSizes; 192 for (RenderBox* child = iterator.first(); child; child = iterator.next()) { 193 LayoutUnit childPreferredSize; 194 if (inflexibleItems.contains(child)) 195 childPreferredSize = inflexibleItems.get(child); 196 else { 197 childPreferredSize = preferredFlexItemContentWidth(child); 198 if (availableFreeSpace > 0 && totalPositiveFlexibility > 0) { 199 childPreferredSize += lroundf(availableFreeSpace * child->style()->flexboxWidthPositiveFlex() / totalPositiveFlexibility); 200 201 Length childMaxWidth = child->style()->maxWidth(); 202 if (!childMaxWidth.isUndefined() && childMaxWidth.isSpecified() && childPreferredSize > childMaxWidth.calcValue(flexboxAvailableLogicalWidth)) { 203 childPreferredSize = childMaxWidth.calcValue(flexboxAvailableLogicalWidth); 204 availableFreeSpace -= childPreferredSize - preferredFlexItemContentWidth(child); 205 totalPositiveFlexibility -= child->style()->flexboxWidthPositiveFlex(); 206 207 inflexibleItems.set(child, childPreferredSize); 208 return false; 209 } 210 } else if (availableFreeSpace < 0 && totalNegativeFlexibility > 0) { 211 childPreferredSize += lroundf(availableFreeSpace * child->style()->flexboxWidthNegativeFlex() / totalNegativeFlexibility); 212 213 Length childMinWidth = child->style()->minWidth(); 214 if (!childMinWidth.isUndefined() && childMinWidth.isSpecified() && childPreferredSize < childMinWidth.calcValue(flexboxAvailableLogicalWidth)) { 215 childPreferredSize = childMinWidth.calcValue(flexboxAvailableLogicalWidth); 216 availableFreeSpace += preferredFlexItemContentWidth(child) - childPreferredSize; 217 totalNegativeFlexibility -= child->style()->flexboxWidthNegativeFlex(); 218 219 inflexibleItems.set(child, childPreferredSize); 220 return false; 221 } 222 } 223 } 224 childSizes.append(childPreferredSize); 225 } 226 227 // Now that we know the sizes, layout and position the flex items. 228 LayoutUnit xOffset = borderLeft() + paddingLeft(); 229 LayoutUnit yOffset = borderTop() + paddingTop(); 230 setHeight(0); 231 size_t i = 0; 232 for (RenderBox* child = iterator.first(); child; child = iterator.next(), ++i) { 233 LayoutUnit childPreferredSize = childSizes[i]; 234 childPreferredSize += child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight(); 235 // FIXME: Handle vertical writing modes with horizontal flexing. 236 child->setOverrideSize(LayoutSize(childPreferredSize, 0)); 237 child->setChildNeedsLayout(true); 238 child->layoutIfNeeded(); 239 240 setHeight(std::max(height(), borderTop() + paddingTop() + child->marginTop() + child->height() + child->marginBottom() + paddingBottom() + borderBottom() + horizontalScrollbarHeight())); 241 242 if (child->style()->marginLeft().isAuto()) 243 child->setMarginLeft(availableFreeSpace > 0 ? lroundf(availableFreeSpace / totalPositiveFlexibility) : 0); 244 if (child->style()->marginRight().isAuto()) 245 child->setMarginRight(availableFreeSpace > 0 ? lroundf(availableFreeSpace / totalPositiveFlexibility) : 0); 246 247 xOffset += child->marginLeft(); 248 child->setLocation(IntPoint(xOffset, yOffset)); 249 xOffset += child->width() + child->marginRight(); 250 } 251 return true; 252 } 253 203 254 } 204 255 -
trunk/Source/WebCore/rendering/RenderFlexibleBox.h
r92628 r93651 51 51 private: 52 52 class FlexibleBoxIterator; 53 typedef WTF::HashMap<const RenderBox*, LayoutUnit> InflexibleFlexItemSize; 53 54 54 55 void layoutHorizontalBlock(bool relayoutChildren); 55 56 56 void computePreferredSize(bool relayoutChildren, FlexibleBoxIterator&, LayoutUnit&, float& totalPositiveFlexibility, float& totalNegativeFlexibility); 57 void computePreferredSizeHorizontal(bool relayoutChildren, FlexibleBoxIterator&, LayoutUnit&, float& totalPositiveFlexibility, float& totalNegativeFlexibility); 58 bool runFreeSpaceAllocationAlgorithmHorizontal(LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize&); 57 59 }; 58 60
Note: See TracChangeset
for help on using the changeset viewer.