Changeset 294804 in webkit
- Timestamp:
- May 25, 2022 10:29:16 AM (2 years ago)
- Location:
- trunk/Source/WebCore/layout/formattingContexts/flex
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingContext.cpp
r294755 r294804 205 205 } 206 206 207 void FlexFormattingContext::computeLogicalWidthForFlexItems(LogicalFlexItems& logicalFlexItemList, const ConstraintsForFlexContent& flexConstraints) 208 { 209 auto& formattingState = this->formattingState(); 210 211 auto flexDirection = root().style().flexDirection(); 212 auto flexDirectionIsInlineAxis = flexDirection == FlexDirection::Row || flexDirection == FlexDirection::RowReverse; 213 auto availableSpace = std::optional<LayoutUnit> { flexDirectionIsInlineAxis ? std::make_optional(flexConstraints.horizontal().logicalWidth) : flexConstraints.availableVerticalSpace() }; 214 215 auto totalGrowth = 0.f; 216 auto totalFlexibleSpace = *availableSpace; 217 auto flexGrowBase = 0.f; 218 Vector<size_t> flexingItems; 219 220 auto computeTotalGrowthAndFlexibleSpace = [&] { 221 // Collect flex items with non-zero flex-grow value. flex-grow: 0 (initial) flex items 222 // don't participate in available space distribution. 223 for (size_t index = 0; index < logicalFlexItemList.size(); ++index) { 224 auto& logicalFlexItem = logicalFlexItemList[index]; 225 if (auto flexGrow = logicalFlexItem.layoutBox->style().flexGrow()) { 226 flexingItems.append(index); 227 totalGrowth += flexGrow; 228 } else 229 totalFlexibleSpace -= logicalFlexItem.rect.width(); 230 } 231 if (totalGrowth) 232 flexGrowBase = totalFlexibleSpace / totalGrowth; 233 }; 234 computeTotalGrowthAndFlexibleSpace(); 235 236 auto totalLogicalWidth = [&] { 237 // This is where we compute how much space the flexing boxes take up if we just 238 // let them flex by their flex-grow value. Note that we can't size them below their minimum content width. 239 // Such flex items are removed from the final overflow distribution. 240 auto accumulatedWidth = LayoutUnit { }; 241 for (auto flexItemIndex : flexingItems) { 242 auto& flexItem = logicalFlexItemList[flexItemIndex]; 243 244 auto flexGrow = flexItem.layoutBox->style().flexGrow(); 245 auto flexedSize = flexGrow * flexGrowBase; 246 auto minimumSize = formattingState.intrinsicWidthConstraintsForBox(*flexItem.layoutBox)->minimum; 247 if (minimumSize >= flexedSize) { 248 accumulatedWidth += minimumSize; 249 totalGrowth -= flexGrow; 250 } else 251 accumulatedWidth += flexedSize; 252 } 253 return accumulatedWidth; 254 }(); 255 auto overflowWidth = totalLogicalWidth - totalFlexibleSpace; 256 ASSERT(overflowWidth >= 0); 257 258 auto computeLogicalWidth = [&] { 259 // Adjust the total grow width by the overflow value (shrink) except when min content with disagrees. 260 for (auto flexItemIndex : flexingItems) { 261 auto& flexItem = logicalFlexItemList[flexItemIndex]; 262 263 auto flexGrow = flexItem.layoutBox->style().flexGrow(); 264 auto flexedSize = flexGrow * flexGrowBase; 265 auto minimumSize = formattingState.intrinsicWidthConstraintsForBox(*flexItem.layoutBox)->minimum; 266 if (minimumSize >= flexedSize) 267 flexItem.rect.setWidth(minimumSize); 268 else { 269 auto distributedOverflow = overflowWidth / totalGrowth * flexGrow; 270 flexItem.rect.setWidth(std::max(minimumSize, LayoutUnit { flexedSize - distributedOverflow })); 271 } 272 } 273 }; 274 computeLogicalWidth(); 275 } 276 207 277 void FlexFormattingContext::layoutInFlowContentForIntegration(const ConstraintsForInFlowContent& constraints) 208 278 { 209 auto& formattingState = this->formattingState();210 279 auto logicalFlexItemList = convertFlexItemsToLogicalSpace(); 211 212 auto totalGrowth = 0.f;213 auto totalFixedSpace = LayoutUnit { };214 215 for (auto& logicalFlexItem : logicalFlexItemList) {216 totalGrowth += logicalFlexItem.layoutBox->style().flexGrow();217 totalFixedSpace += formattingState.intrinsicWidthConstraintsForBox(*logicalFlexItem.layoutBox)->minimum;218 }219 280 220 281 auto flexConstraints = downcast<ConstraintsForFlexContent>(constraints); 221 282 auto logicalLeft = LayoutUnit { }; 222 283 auto logicalTop = LayoutUnit { }; 223 auto flexDirection = root().style().flexDirection(); 224 auto flexDirectionIsInlineAxis = flexDirection == FlexDirection::Row || flexDirection == FlexDirection::RowReverse; 225 auto availableSpace = std::optional<LayoutUnit> { flexDirectionIsInlineAxis ? std::make_optional(flexConstraints.horizontal().logicalWidth) : flexConstraints.availableVerticalSpace() }; 226 auto flexibleSpace = availableSpace.value_or(0_lu) - totalFixedSpace; 284 285 computeLogicalWidthForFlexItems(logicalFlexItemList, flexConstraints); 227 286 228 287 for (auto& logicalFlexItem : logicalFlexItemList) { 229 288 logicalFlexItem.rect.setTopLeft({ logicalLeft, logicalTop }); 230 289 logicalLeft = logicalFlexItem.rect.right(); 231 auto growFlexItemIfApplicable = [&] {232 if (flexibleSpace <= 0)233 return;234 auto grow = logicalFlexItem.layoutBox->style().flexGrow();235 if (!grow)236 return;237 // This value specifies the flex grow factor, which determines how much the flex item will grow relative to the238 // rest of the flex items in the flex container when positive free space is distributed.239 ASSERT(availableSpace.has_value());240 // FIXME: This is still slighly incorrect.241 logicalFlexItem.rect.setWidth(LayoutUnit { formattingState.intrinsicWidthConstraintsForBox(*logicalFlexItem.layoutBox)->minimum + (flexibleSpace * grow / totalGrowth) });242 // FIXME: constrain logical width on min width.243 };244 growFlexItemIfApplicable();245 290 } 246 291 setFlexItemsGeometry(logicalFlexItemList, flexConstraints); -
trunk/Source/WebCore/layout/formattingContexts/flex/FlexFormattingContext.h
r294623 r294804 66 66 LogicalFlexItems convertFlexItemsToLogicalSpace(); 67 67 void setFlexItemsGeometry(const LogicalFlexItems&, const ConstraintsForFlexContent&); 68 void computeLogicalWidthForFlexItems(LogicalFlexItems&, const ConstraintsForFlexContent&); 68 69 69 70 const FlexFormattingState& formattingState() const { return downcast<FlexFormattingState>(FormattingContext::formattingState()); }
Note: See TracChangeset
for help on using the changeset viewer.