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

📄 renderflexiblebox.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            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()+offset, child->y());                    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->x()+offset, child->y());                child = iterator.next();            }        }    }        child = iterator.first();    while (child && child->isPositioned()) {        child = iterator.next();    }        if (child) {        m_overflowLeft = min(child->x() + child->overflowLeft(false), m_overflowLeft);        RenderBox* lastChild = child;        while ((child = iterator.next())) {            if (!child->isPositioned())                lastChild = child;        }        m_overflowWidth = max(lastChild->x() + lastChild->overflowWidth(false), m_overflowWidth);    }        // 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::layoutVerticalBox(bool relayoutChildren){    int xPos = borderLeft() + paddingLeft();    int yPos = borderTop() + paddingTop();    if( style()->direction() == RTL )        xPos = width() - paddingRight() - borderRight();    int toAdd = borderBottom() + paddingBottom() + horizontalScrollbarHeight();    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);    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 confine the line clamp ugliness to vertical flexible boxes (thus keeping it out of    // mainstream block layout); this is not really part of the XUL box model.    bool haveLineClamp = style()->lineClamp() >= 0 && style()->lineClamp() <= 100;    if (haveLineClamp) {        int maxLineCount = 0;        child = iterator.first();        while (child) {            if (!child->isPositioned()) {                if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())) ||                    (child->style()->height().isAuto() && child->isBlockFlow() && !child->needsLayout())) {                    child->setChildNeedsLayout(true, false);                                        // Dirty all the positioned objects.                    if (child->isRenderBlock()) {                        toRenderBlock(child)->markPositionedObjectsForLayout();                        toRenderBlock(child)->clearTruncation();                    }                }                child->layoutIfNeeded();                if (child->style()->height().isAuto() && child->isBlockFlow())                    maxLineCount = max(maxLineCount, toRenderBlock(child)->lineCount());            }            child = iterator.next();        }                // Get the # of lines and then alter all block flow children with auto height to use the        // specified height. We always try to leave room for at least one line.        int numVisibleLines = max(1, static_cast<int>((maxLineCount + 1) * style()->lineClamp() / 100.0));        if (numVisibleLines < maxLineCount) {            for (child = iterator.first(); child; child = iterator.next()) {                if (child->isPositioned() || !child->style()->height().isAuto() || !child->isBlockFlow())                    continue;                                RenderBlock* blockChild = toRenderBlock(child);                int lineCount = blockChild->lineCount();                if (lineCount <= numVisibleLines)                    continue;                                int newHeight = blockChild->heightForLineCount(numVisibleLines);                if (newHeight == child->height())                    continue;                                child->setChildNeedsLayout(true, false);                child->setOverrideSize(newHeight);                m_flexingChildren = true;                child->layoutIfNeeded();                m_flexingChildren = false;                child->setOverrideSize(-1);                                // FIXME: For now don't support RTL.                if (style()->direction() != LTR)                    continue;                                // Get the last line                RootInlineBox* lastLine = blockChild->lineAtIndex(lineCount-1);                if (!lastLine)                    continue;                                // See if the last item is an anchor                InlineBox* anchorBox = lastLine->lastChild();                if (!anchorBox)                    continue;                if (!anchorBox->renderer()->node())                    continue;                if (!anchorBox->renderer()->node()->isLink())                    continue;                                RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1);                if (!lastVisibleLine)                    continue;                const UChar ellipsisAndSpace[2] = { horizontalEllipsis, ' ' };                DEFINE_STATIC_LOCAL(AtomicString, ellipsisAndSpaceStr, (ellipsisAndSpace, 2));                const Font& font = style(numVisibleLines == 1)->font();                int ellipsisAndSpaceWidth = font.width(TextRun(ellipsisAndSpace, 2));                // Get ellipsis width + " " + anchor width                int totalWidth = ellipsisAndSpaceWidth + anchorBox->width();                                // See if this width can be accommodated on the last visible line                RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer());                RenderBlock* srcBlock = toRenderBlock(lastLine->renderer());                                // FIXME: Directions of src/destBlock could be different from our direction and from one another.                if (srcBlock->style()->direction() != LTR)                    continue;                if (destBlock->style()->direction() != LTR)                    continue;                int blockEdge = destBlock->rightOffset(lastVisibleLine->y(), false);                if (!lastVisibleLine->canAccommodateEllipsis(true, blockEdge,                                                              lastVisibleLine->x() + lastVisibleLine->width(),                                                             totalWidth))                    continue;                // Let the truncation code kick in.                lastVisibleLine->placeEllipsis(ellipsisAndSpaceStr, true, blockEdge, totalWidth, anchorBox);                destBlock->setHasMarkupTruncation(true);            }        }    }    // We do 2 passes.  The first pass is simply to lay everyone out at    // their preferred widths.  The second pass handles flexing the children.    // Our first pass is done without flexing.  We simply lay the children    // out within the box.    do {        setHeight(borderTop() + paddingTop());        int minHeight = height() + toAdd;        m_overflowHeight = height();        child = iterator.first();        while (child) {            // make sure we relayout children if we need it.            if (!haveLineClamp && (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent()))))                child->setChildNeedsLayout(true, false);                if (child->isPositioned())            {                child->containingBlock()->insertPositionedObject(child);                if (child->style()->hasStaticX()) {                    if (style()->direction() == LTR)                        child->layer()->setStaticX(borderLeft()+paddingLeft());                    else                        child->layer()->setStaticX(borderRight()+paddingRight());                }                if (child->style()->hasStaticY())                    child->layer()->setStaticY(height());                child = iterator.next();                continue;            }                 // Compute the child's vertical margins.            child->calcVerticalMargins();                // Add in the child's marginTop to our height.            setHeight(height() + child->marginTop());                // Now do a layout.            child->layoutIfNeeded();                // We can place the child now, using our value of box-align.            int childX = borderLeft() + paddingLeft();            switch (style()->boxAlign()) {                case BCENTER:                case BBASELINE: // Baseline just maps to center for vertical boxes                    childX += child->marginLeft() + max(0, (contentWidth() - (child->width() + child->marginLeft() + child->marginRight()))/2);                    break;                case BEND:                    if (style()->direction() == RTL)                        childX += child->marginLeft();                    else                        childX += contentWidth() - child->marginRight() - child->width();                    break;                default: // BSTART/BSTRETCH                    if (style()->direction() == LTR)                        childX += child->marginLeft();                    else                        childX += contentWidth() - child->marginRight() - child->width();                    break;            }                // Place the child.            placeChild(child, childX, height());            setHeight(height() + child->height() + child->marginBottom());                if (child->isRenderBlock())                toRenderBlock(child)->addVisualOverflow(toRenderBlock(child)->floatRect());            // See if this child has made our overflow need to grow.

⌨️ 快捷键说明

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