⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 renderflexiblebox.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            m_overflowHeight = max(m_overflowWidth, reflection.right());        }    }    statePusher.pop();    // Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if    // we overflow or not.    if (hasOverflowClip())        layer()->updateScrollInfoAfterLayout();    // Repaint with our new bounds if they are different from our old bounds.    repainter.repaintAfterLayout();        setNeedsLayout(false);}void RenderFlexibleBox::layoutHorizontalBox(bool relayoutChildren){    int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();    int yPos = borderTop() + paddingTop();    int xPos = borderLeft() + paddingLeft();    bool heightSpecified = false;    int oldHeight = 0;        unsigned int highestFlexGroup = 0;    unsigned int lowestFlexGroup = 0;    bool haveFlex = false;    int remainingSpace = 0;    m_overflowHeight = height();    // The first walk over our kids is to find out if we have any flexible children.    FlexBoxIterator iterator(this);    RenderBox* child = iterator.next();    while (child) {        // Check to see if this child flexes.        if (!child->isPositioned() && child->style()->boxFlex() > 0.0f) {            // We always have to lay out flexible objects again, since the flex distribution            // may have changed, and we need to reallocate space.            child->setOverrideSize(-1);            if (!relayoutChildren)                child->setChildNeedsLayout(true, false);            haveFlex = true;            unsigned int flexGroup = child->style()->boxFlexGroup();            if (lowestFlexGroup == 0)                lowestFlexGroup = flexGroup;            if (flexGroup < lowestFlexGroup)                lowestFlexGroup = flexGroup;            if (flexGroup > highestFlexGroup)                highestFlexGroup = flexGroup;        }        child = iterator.next();    }        // We do 2 passes.  The first pass is simply to lay everyone out at    // their preferred widths.  The second pass handles flexing the children.    do {        // Reset our height.        setHeight(yPos);        m_overflowHeight = height();        xPos = borderLeft() + paddingLeft();                        // Our first pass is done without flexing.  We simply lay the children        // out within the box.  We have to do a layout first in order to determine        // our box's intrinsic height.        int maxAscent = 0, maxDescent = 0;        child = iterator.first();        while (child) {            // make sure we relayout children if we need it.            if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))                child->setChildNeedsLayout(true, false);                        if (child->isPositioned()) {                child = iterator.next();                continue;            }                // Compute the child's vertical margins.            child->calcVerticalMargins();                // Now do the layout.            child->layoutIfNeeded();                // Update our height and overflow height.            if (style()->boxAlign() == BBASELINE) {                int ascent = child->firstLineBoxBaseline();                if (ascent == -1)                    ascent = child->height() + child->marginBottom();                ascent += child->marginTop();                int descent = (child->marginTop() + child->height() + child->marginBottom()) - ascent;                                // Update our maximum ascent.                maxAscent = max(maxAscent, ascent);                                // Update our maximum descent.                maxDescent = max(maxDescent, descent);                                // Now update our height.                setHeight(max(yPos + maxAscent + maxDescent, height()));            }            else                setHeight(max(height(), yPos + child->marginTop() + child->height() + child->marginBottom()));            child = iterator.next();        }                if (!iterator.first() && hasLineIfEmpty())            setHeight(height() + lineHeight(true, true));                setHeight(height() + toAdd);        // Always make sure our overflowheight is at least our height.        if (m_overflowHeight < height())            m_overflowHeight = height();                oldHeight = height();        calcHeight();        relayoutChildren = false;        if (oldHeight != height())            heightSpecified = true;                // Now that our height is actually known, we can place our boxes.        m_stretchingChildren = (style()->boxAlign() == BSTRETCH);        child = iterator.first();        while (child) {            if (child->isPositioned()) {                child->containingBlock()->insertPositionedObject(child);                if (child->style()->hasStaticX()) {                    if (style()->direction() == LTR)                        child->layer()->setStaticX(xPos);                    else child->layer()->setStaticX(width() - xPos);                }                if (child->style()->hasStaticY())                    child->layer()->setStaticY(yPos);                child = iterator.next();                continue;            }                // We need to see if this child's height has changed, since we make block elements            // fill the height of a containing box by default.            // Now do a layout.            int oldChildHeight = child->height();            child->calcHeight();            if (oldChildHeight != child->height())                child->setChildNeedsLayout(true, false);            child->layoutIfNeeded();                // We can place the child now, using our value of box-align.            xPos += child->marginLeft();            int childY = yPos;            switch (style()->boxAlign()) {                case BCENTER:                    childY += child->marginTop() + max(0, (contentHeight() - (child->height() + child->marginTop() + child->marginBottom()))/2);                    break;                case BBASELINE: {                    int ascent = child->firstLineBoxBaseline();                    if (ascent == -1)                        ascent = child->height() + child->marginBottom();                    ascent += child->marginTop();                    childY += child->marginTop() + (maxAscent - ascent);                    break;                }                case BEND:                    childY += contentHeight() - child->marginBottom() - child->height();                    break;                default: // BSTART                    childY += child->marginTop();                    break;            }            placeChild(child, xPos, childY);            if (child->isRenderBlock())                toRenderBlock(child)->addVisualOverflow(toRenderBlock(child)->floatRect());            m_overflowHeight = max(m_overflowHeight, childY + child->overflowHeight(false));            m_overflowTop = min(m_overflowTop, child->y() + child->overflowTop(false));                        xPos += child->width() + child->marginRight();                child = iterator.next();        }        remainingSpace = borderLeft() + paddingLeft() + contentWidth() - xPos;                m_stretchingChildren = false;        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->overrideWidth() + 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->overrideWidth() + 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);    m_flexingChildren = false;        if (remainingSpace > 0 && ((style()->direction() == LTR && style()->boxPack() != BSTART) ||                               (style()->direction() == RTL && style()->boxPack() != BEND))) {        // Children must be repositioned.        int offset = 0;        if (style()->boxPack() == BJUSTIFY) {            // Determine the total number of children.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -