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

📄 render_flexbox.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            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.        m_height = yPos;        m_overflowHeight = m_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->marginTop() + child->getBaselineOfFirstLineBox();                if (ascent == -1)                    ascent = child->marginTop() + child->height() + child->marginBottom();                int descent = (child->marginTop() + child->height() + child->marginBottom()) - ascent;                                // Update our maximum ascent.                maxAscent = kMax(maxAscent, ascent);                                // Update our maximum descent.                maxDescent = kMax(maxDescent, descent);                                // Now update our height.                m_height = kMax(yPos + maxAscent + maxDescent, m_height);            }            else                m_height = kMax(m_height, yPos + child->marginTop() + child->height() + child->marginBottom());            child = iterator.next();        }        m_height += toAdd;        // Always make sure our overflowheight is at least our height.        if (m_overflowHeight < m_height)            m_overflowHeight = m_height;                oldHeight = m_height;        calcHeight();        relayoutChildren = false;        if (oldHeight != m_height) {            heightSpecified = true;                // If the block got expanded in size, then increase our overflowheight to match.            if (m_overflowHeight > m_height)                m_overflowHeight -= (borderBottom() + paddingBottom());            if (m_overflowHeight < m_height)                m_overflowHeight = m_height;        }                // 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->hasStaticX()) {                    if (style()->direction() == LTR)                        child->setStaticX(xPos);                    else child->setStaticX(width() - xPos);                }                if (child->hasStaticY())                    child->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();            static_cast<RenderBox*>(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() + (contentHeight() - (child->height() + child->marginTop() + child->marginBottom()))/2;                    break;                case BBASELINE: {                    int ascent = child->marginTop() + child->getBaselineOfFirstLineBox();                    if (ascent == -1)                        ascent = child->marginTop() + child->height() + child->marginBottom();                    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);            m_overflowHeight = kMax(m_overflowHeight, childY + child->overflowHeight(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).                    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 ? kMin(spaceAvailableThisPass, projectedFlex) : kMax(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();                    }                } while (groupRemainingSpace);            }            // We didn't find any children that could grow.            if (haveFlex && !m_flexingChildren)                haveFlex = false;        }    } while (haveFlex);    m_flexingChildren = false;        if (xPos > m_overflowWidth)        m_overflowWidth = xPos;    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.            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->xPos()+offset, child->yPos());                    child = iterator.next();                }            }        }        else {            if (style()->boxPack() == BCENTER)                offset += remainingSpace/2;            else // END for LTR, START for RTL                offset += remainingSpace;            child = iterator.first();            while (child) {                if (child->isPositioned()) {                    child = iterator.next();                    continue;                }                placeChild(child, child->xPos()+offset, child->yPos());                child = iterator.next();            }        }    }        // 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)        m_height = oldHeight;}void RenderFlexibleBox::layoutVerticalBox(bool relayoutChildren){    int xPos = borderLeft() + paddingLeft();    int yPos = borderTop() + paddingTop();    if( style()->direction() == RTL )        xPos = m_width - paddingRight() - borderRight();    int toAdd = borderBottom() + paddingBottom();    bool heightSpecified = false;    int oldHeight = 0;        unsigned int highestFlexGroup = 0;    unsigned int lowestFlexGroup = 0;    bool haveFlex = false;    int remainingSpace = 0;        // The first walk over our kids is to find out if we have any flexible children.    FlexBoxIterator iterator(this);    RenderObject *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);            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();    }#if APPLE_CHANGES    // We confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of    // mainstream block layout) and put it all inside APPLE_CHANGES to denote that this is not    // really part of the XUL box model.    bool haveLineClamp = style()->lineClamp() >= 0 && style()->lineClamp() <= 100;    if (haveLineClamp) {        int maxLineCount = 1;        child = iterator.first();        while (child) {            if (!child->isPositioned()) {                if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())) ||                    (child->style()->height().isVariable() && child->isBlockFlow() && !child->needsLayout())) {                    child->setChildNeedsLayout(true);                                        // Dirty all the positioned objects.                    static_cast<RenderBlock*>(child)->markPositionedObjectsForLayout();                    static_cast<RenderBlock*>(child)->clearTruncation();                }                child->layoutIfNeeded();                if (child->style()->height().isVariable() && child->isBlockFlow())                    maxLineCount = kMax(maxLineCount, static_cast<RenderBlock*>(child)->lineCount());            }            child = iterator.next();        }                // Get the # of lines and then alter all block flow children with auto height to use the        // specified height.        int numVisibleLines = int(maxLineCount*style()->lineClamp()/100.0 + 1.0);        if (numVisibleLines < maxLineCount) {            for (child = iterator.first(); child; child = iterator.next()) {                if (child->isPositioned() || !child->style()->height().isVariable() || !child->isBlockFlow())                    continue;                                RenderBlock* blockChild = static_cast<RenderBlock*>(child);                int lineCount = blockChild->lineCount();                if (lineCount <= numVisibleLines) continue;                                int newHeight = blockChild->heightForLineCount(numVisibleLines);                if (newHeight == child->height()) continue;                                child->setChildNeedsLayout(true);                child->setOverrideSize(newHeight);                m_flexingChildren = true;                child->layoutIfNeeded();                m_flexingChildren = false;

⌨️ 快捷键说明

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