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

📄 render_flexbox.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                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->object()->element()) continue;                if (!anchorBox->object()->element()->hasAnchor()) continue;                                RootInlineBox* lastVisibleLine = blockChild->lineAtIndex(numVisibleLines-1);                if (!lastVisibleLine) continue;                const unsigned short ellipsisAndSpace[2] = { 0x2026, ' ' };                static AtomicString ellipsisAndSpaceStr(ellipsisAndSpace, 2);                const Font& font = style(numVisibleLines == 1)->htmlFont();                int ellipsisAndSpaceWidth = font.width(const_cast<QChar*>(ellipsisAndSpaceStr.unicode()), 2, 0, 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 = static_cast<RenderBlock*>(lastVisibleLine->object());                RenderBlock* srcBlock = static_cast<RenderBlock*>(lastLine->object());                                // 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->yPos());                if (!lastVisibleLine->canAccommodateEllipsis(true, blockEdge,                                                              lastVisibleLine->xPos() + lastVisibleLine->width(),                                                             totalWidth))                    continue;                // Let the truncation code kick in.                lastVisibleLine->placeEllipsis(ellipsisAndSpaceStr, true, blockEdge, totalWidth, anchorBox);                destBlock->setHasMarkupTruncation(true);            }        }    }#endif    // 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 {        m_height = borderTop() + paddingTop();        int minHeight = m_height + toAdd;        m_overflowHeight = m_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);                if (child->isPositioned())            {                child->containingBlock()->insertPositionedObject(child);                if (child->hasStaticX()) {                    if (style()->direction() == LTR)                        child->setStaticX(borderLeft()+paddingLeft());                    else                        child->setStaticX(borderRight()+paddingRight());                }                if (child->hasStaticY())                    child->setStaticY(m_height);                child = iterator.next();                continue;            }                 // Compute the child's vertical margins.            child->calcVerticalMargins();                // Add in the child's marginTop to our height.            m_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() + (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, m_height);            m_height += child->height() + child->marginBottom();                // See if this child has made our overflow need to grow.            // XXXdwh Work with left overflow as well as right overflow.            int rightChildPos = child->xPos() + kMax(child->overflowWidth(false), child->width());            if (rightChildPos > m_overflowWidth)                m_overflowWidth = rightChildPos;                        child = iterator.next();        }        yPos = m_height;        m_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 (m_height < minHeight)            m_height = minHeight;        // Always make sure our overflowheight is at least our height.        if (m_overflowHeight < m_height)            m_overflowHeight = m_height;        // Now we have to calc our height, so we know how much space we have remaining.        oldHeight = m_height;        calcHeight();        if (oldHeight != m_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).                    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->overrideHeight() + 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);    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->xPos(), child->yPos()+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->xPos(), child->yPos()+offset);                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::placeChild(RenderObject* child, int x, int y){    int oldChildX = child->xPos();    int oldChildY = child->yPos();    // Place the child.    child->setPos(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(oldChildX, oldChildY);}int RenderFlexibleBox::allowedChildFlex(RenderObject* 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().value != UNDEFINED &&                child->style()->maxWidth().isFixed())                maxW = child->style()->maxWidth().value;            else if (child->style()->maxWidth().type == Intrinsic)                maxW = child->maxWidth();            else if (child->style()->maxWidth().type == MinIntrinsic)                maxW = child->minWidth();            int allowedGrowth = kMax(0, maxW - w);            return allowedGrowth;        }        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().value != UNDEFINED &&                child->style()->maxHeight().isFixed())                maxH = child->style()->maxHeight().value;            int allowedGrowth = kMax(0, maxH - h);            return allowedGrowth;        }    }    // FIXME: For now just handle fixed values.    if (isHorizontal()) {        int minW = child->minWidth();        int w = child->contentWidth();        if (child->style()->minWidth().isFixed())            minW = child->style()->minWidth().value;        else if (child->style()->minWidth().type == Intrinsic)            minW = child->maxWidth();        else if (child->style()->minWidth().type == MinIntrinsic)            minW = child->minWidth();                    int allowedShrinkage = kMin(0, minW - w);        return allowedShrinkage;    }    else {        if (child->style()->minHeight().isFixed()) {            int minH = child->style()->minHeight().value;            int h = child->contentHeight();            int allowedShrinkage = kMin(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 khtml

⌨️ 快捷键说明

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