📄 renderflexiblebox.cpp
字号:
m_overflowWidth = max(child->x() + child->overflowWidth(false), m_overflowWidth); m_overflowLeft = min(child->x() + child->overflowLeft(false), m_overflowLeft); child = iterator.next(); } yPos = height(); if (!iterator.first() && hasLineIfEmpty()) setHeight(height() + lineHeight(true, true)); setHeight(height() + toAdd); // Negative margins can cause our height to shrink below our minimal height (border/padding). // If this happens, ensure that the computed height is increased to the minimal height. if (height() < minHeight) setHeight(minHeight); // Always make sure our overflowheight is at least our height. if (m_overflowHeight < height()) m_overflowHeight = height(); // Now we have to calc our height, so we know how much space we have remaining. oldHeight = height(); calcHeight(); if (oldHeight != height()) heightSpecified = true; remainingSpace = borderTop() + paddingTop() + contentHeight() - yPos; if (m_flexingChildren) haveFlex = false; // We're done. else if (haveFlex) { // We have some flexible objects. See if we need to grow/shrink them at all. if (!remainingSpace) break; // Allocate the remaining space among the flexible objects. If we are trying to // grow, then we go from the lowest flex group to the highest flex group. For shrinking, // we go from the highest flex group to the lowest group. bool expanding = remainingSpace > 0; unsigned int start = expanding ? lowestFlexGroup : highestFlexGroup; unsigned int end = expanding? highestFlexGroup : lowestFlexGroup; for (unsigned int i = start; i <= end && remainingSpace; i++) { // Always start off by assuming the group can get all the remaining space. int groupRemainingSpace = remainingSpace; do { // Flexing consists of multiple passes, since we have to change ratios every time an object hits its max/min-width // For a given pass, we always start off by computing the totalFlex of all objects that can grow/shrink at all, and // computing the allowed growth before an object hits its min/max width (and thus // forces a totalFlex recomputation). int groupRemainingSpaceAtBeginning = groupRemainingSpace; float totalFlex = 0.0f; child = iterator.first(); while (child) { if (allowedChildFlex(child, expanding, i)) totalFlex += child->style()->boxFlex(); child = iterator.next(); } child = iterator.first(); int spaceAvailableThisPass = groupRemainingSpace; while (child) { int allowedFlex = allowedChildFlex(child, expanding, i); if (allowedFlex) { int projectedFlex = (allowedFlex == INT_MAX) ? allowedFlex : (int)(allowedFlex * (totalFlex / child->style()->boxFlex())); spaceAvailableThisPass = expanding ? min(spaceAvailableThisPass, projectedFlex) : max(spaceAvailableThisPass, projectedFlex); } child = iterator.next(); } // The flex groups may not have any flexible objects this time around. if (!spaceAvailableThisPass || totalFlex == 0.0f) { // If we just couldn't grow/shrink any more, then it's time to transition to the next flex group. groupRemainingSpace = 0; continue; } // Now distribute the space to objects. child = iterator.first(); while (child && spaceAvailableThisPass && totalFlex) { if (allowedChildFlex(child, expanding, i)) { int spaceAdd = (int)(spaceAvailableThisPass * (child->style()->boxFlex()/totalFlex)); if (spaceAdd) { child->setOverrideSize(child->overrideHeight() + spaceAdd); m_flexingChildren = true; relayoutChildren = true; } spaceAvailableThisPass -= spaceAdd; remainingSpace -= spaceAdd; groupRemainingSpace -= spaceAdd; totalFlex -= child->style()->boxFlex(); } child = iterator.next(); } if (groupRemainingSpace == groupRemainingSpaceAtBeginning) { // this is not advancing, avoid getting stuck by distributing the remaining pixels child = iterator.first(); int spaceAdd = groupRemainingSpace > 0 ? 1 : -1; while (child && groupRemainingSpace) { if (allowedChildFlex(child, expanding, i)) { child->setOverrideSize(child->overrideHeight() + spaceAdd); m_flexingChildren = true; relayoutChildren = true; remainingSpace -= spaceAdd; groupRemainingSpace -= spaceAdd; } child = iterator.next(); } } } while (groupRemainingSpace); } // We didn't find any children that could grow. if (haveFlex && !m_flexingChildren) haveFlex = false; } } while (haveFlex); if (style()->boxPack() != BSTART && remainingSpace > 0) { // Children must be repositioned. int offset = 0; if (style()->boxPack() == BJUSTIFY) { // Determine the total number of children. int totalChildren = 0; child = iterator.first(); while (child) { if (child->isPositioned()) { child = iterator.next(); continue; } totalChildren++; child = iterator.next(); } // Iterate over the children and space them out according to the // justification level. if (totalChildren > 1) { totalChildren--; bool firstChild = true; child = iterator.first(); while (child) { if (child->isPositioned()) { child = iterator.next(); continue; } if (firstChild) { firstChild = false; child = iterator.next(); continue; } offset += remainingSpace/totalChildren; remainingSpace -= (remainingSpace/totalChildren); totalChildren--; placeChild(child, child->x(), child->y()+offset); child = iterator.next(); } } } else { if (style()->boxPack() == BCENTER) offset += remainingSpace/2; else // END offset += remainingSpace; child = iterator.first(); while (child) { if (child->isPositioned()) { child = iterator.next(); continue; } placeChild(child, child->x(), child->y()+offset); child = iterator.next(); } } } child = iterator.first(); while (child && child->isPositioned()) { child = iterator.next(); } if (child) { m_overflowTop = min(child->y() + child->overflowTop(false), m_overflowTop); RenderBox* lastChild = child; while ((child = iterator.next())) { if (!child->isPositioned()) lastChild = child; } m_overflowHeight = max(lastChild->y() + lastChild->overflowHeight(false), m_overflowHeight); } // So that the calcHeight in layoutBlock() knows to relayout positioned objects because of // a height change, we revert our height back to the intrinsic height before returning. if (heightSpecified) setHeight(oldHeight); }void RenderFlexibleBox::placeChild(RenderBox* child, int x, int y){ IntRect oldRect(child->x(), child->y() , child->width(), child->height()); // Place the child. child->setLocation(x, y); // If the child moved, we have to repaint it as well as any floating/positioned // descendants. An exception is if we need a layout. In this case, we know we're going to // repaint ourselves (and the child) anyway. if (!selfNeedsLayout() && child->checkForRepaintDuringLayout()) child->repaintDuringLayoutIfMoved(oldRect);}int RenderFlexibleBox::allowedChildFlex(RenderBox* child, bool expanding, unsigned int group){ if (child->isPositioned() || child->style()->boxFlex() == 0.0f || child->style()->boxFlexGroup() != group) return 0; if (expanding) { if (isHorizontal()) { // FIXME: For now just handle fixed values. int maxW = INT_MAX; int w = child->overrideWidth() - (child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight()); if (!child->style()->maxWidth().isUndefined() && child->style()->maxWidth().isFixed()) maxW = child->style()->maxWidth().value(); else if (child->style()->maxWidth().type() == Intrinsic) maxW = child->maxPrefWidth(); else if (child->style()->maxWidth().type() == MinIntrinsic) maxW = child->minPrefWidth(); if (maxW == INT_MAX) return maxW; return max(0, maxW - w); } else { // FIXME: For now just handle fixed values. int maxH = INT_MAX; int h = child->overrideHeight() - (child->borderTop() + child->borderBottom() + child->paddingTop() + child->paddingBottom()); if (!child->style()->maxHeight().isUndefined() && child->style()->maxHeight().isFixed()) maxH = child->style()->maxHeight().value(); if (maxH == INT_MAX) return maxH; return max(0, maxH - h); } } // FIXME: For now just handle fixed values. if (isHorizontal()) { int minW = child->minPrefWidth(); int w = child->overrideWidth() - (child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight()); if (child->style()->minWidth().isFixed()) minW = child->style()->minWidth().value(); else if (child->style()->minWidth().type() == Intrinsic) minW = child->maxPrefWidth(); else if (child->style()->minWidth().type() == MinIntrinsic) minW = child->minPrefWidth(); int allowedShrinkage = min(0, minW - w); return allowedShrinkage; } else { if (child->style()->minHeight().isFixed()) { int minH = child->style()->minHeight().value(); int h = child->overrideHeight() - (child->borderLeft() + child->borderRight() + child->paddingLeft() + child->paddingRight()); int allowedShrinkage = min(0, minH - h); return allowedShrinkage; } } return 0;}const char *RenderFlexibleBox::renderName() const{ if (isFloating()) return "RenderFlexibleBox (floating)"; if (isPositioned()) return "RenderFlexibleBox (positioned)"; if (isRelPositioned()) return "RenderFlexibleBox (relative positioned)"; return "RenderFlexibleBox";}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -