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

📄 renderbox.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (isTableCell() || (isInline() && !isReplaced()))        return;    if (isPositioned())        calcAbsoluteVertical();    else {        calcVerticalMargins();        // For tables, calculate margins only.        if (isTable())            return;        Length h;        bool inHorizontalBox = parent()->isFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL;        bool stretching = parent()->style()->boxAlign() == BSTRETCH;        bool treatAsReplaced = shouldCalculateSizeAsReplaced() && (!inHorizontalBox || !stretching);        bool checkMinMaxHeight = false;        // The parent box is flexing us, so it has increased or decreased our height.  We have to        // grab our cached flexible height.        if (hasOverrideSize() && parent()->isFlexibleBox() && parent()->style()->boxOrient() == VERTICAL                && parent()->isFlexingChildren())            h = Length(overrideSize() - borderTop() - borderBottom() - paddingTop() - paddingBottom(), Fixed);        else if (treatAsReplaced)            h = Length(calcReplacedHeight(), Fixed);        else {            h = style()->height();            checkMinMaxHeight = true;        }        // Block children of horizontal flexible boxes fill the height of the box.        if (h.isAuto() && parent()->isFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL                && parent()->isStretchingChildren()) {            h = Length(parentBox()->contentHeight() - marginTop() - marginBottom() -                       borderTop() - paddingTop() - borderBottom() - paddingBottom(), Fixed);            checkMinMaxHeight = false;        }        int heightResult;        if (checkMinMaxHeight) {            heightResult = calcHeightUsing(style()->height());            if (heightResult == -1)                heightResult = height();            int minH = calcHeightUsing(style()->minHeight()); // Leave as -1 if unset.            int maxH = style()->maxHeight().isUndefined() ? heightResult : calcHeightUsing(style()->maxHeight());            if (maxH == -1)                maxH = heightResult;            heightResult = min(maxH, heightResult);            heightResult = max(minH, heightResult);        } else            // The only times we don't check min/max height are when a fixed length has            // been given as an override.  Just use that.  The value has already been adjusted            // for box-sizing.            heightResult = h.value() + borderTop() + borderBottom() + paddingTop() + paddingBottom();            setHeight(heightResult);        }    // WinIE quirk: The <html> block always fills the entire canvas in quirks mode.  The <body> always fills the    // <html> block in quirks mode.  Only apply this quirk if the block is normal flow and no height    // is specified.    if (stretchesToViewHeight() && !document()->printing()) {        int margins = collapsedMarginTop() + collapsedMarginBottom();        int visHeight = view()->viewHeight();        if (isRoot())            setHeight(max(height(), visHeight - margins));        else {            int marginsBordersPadding = margins + parentBox()->marginTop() + parentBox()->marginBottom()                + parentBox()->borderTop() + parentBox()->borderBottom()                + parentBox()->paddingTop() + parentBox()->paddingBottom();            setHeight(max(height(), visHeight - marginsBordersPadding));        }    }}int RenderBox::calcHeightUsing(const Length& h){    int height = -1;    if (!h.isAuto()) {        if (h.isFixed())            height = h.value();        else if (h.isPercent())            height = calcPercentageHeight(h);        if (height != -1) {            height = calcBorderBoxHeight(height);            return height;        }    }    return height;}int RenderBox::calcPercentageHeight(const Length& height){    int result = -1;    bool includeBorderPadding = isTable();    RenderBlock* cb = containingBlock();    if (style()->htmlHacks()) {        // In quirks mode, blocks with auto height are skipped, and we keep looking for an enclosing        // block that may have a specified height and then use it.  In strict mode, this violates the        // specification, which states that percentage heights just revert to auto if the containing        // block has an auto height.        while (!cb->isRenderView() && !cb->isBody() && !cb->isTableCell() && !cb->isPositioned() && cb->style()->height().isAuto()) {            cb = cb->containingBlock();            cb->addPercentHeightDescendant(this);        }    }    // A positioned element that specified both top/bottom or that specifies height should be treated as though it has a height    // explicitly specified that can be used for any percentage computations.    bool isPositionedWithSpecifiedHeight = cb->isPositioned() && (!cb->style()->height().isAuto() || (!cb->style()->top().isAuto() && !cb->style()->bottom().isAuto()));    // Table cells violate what the CSS spec says to do with heights.  Basically we    // don't care if the cell specified a height or not.  We just always make ourselves    // be a percentage of the cell's current content height.    if (cb->isTableCell()) {        result = cb->overrideSize();        if (result == -1) {            // Normally we would let the cell size intrinsically, but scrolling overflow has to be            // treated differently, since WinIE lets scrolled overflow regions shrink as needed.            // While we can't get all cases right, we can at least detect when the cell has a specified            // height or when the table has a specified height.  In these cases we want to initially have            // no size and allow the flexing of the table or the cell to its specified height to cause us            // to grow to fill the space.  This could end up being wrong in some cases, but it is            // preferable to the alternative (sizing intrinsically and making the row end up too big).            RenderTableCell* cell = static_cast<RenderTableCell*>(cb);            if (scrollsOverflowY() && (!cell->style()->height().isAuto() || !cell->table()->style()->height().isAuto()))                return 0;            return -1;        }        includeBorderPadding = true;    }    // Otherwise we only use our percentage height if our containing block had a specified    // height.    else if (cb->style()->height().isFixed())        result = cb->calcContentBoxHeight(cb->style()->height().value());    else if (cb->style()->height().isPercent() && !isPositionedWithSpecifiedHeight) {        // We need to recur and compute the percentage height for our containing block.        result = cb->calcPercentageHeight(cb->style()->height());        if (result != -1)            result = cb->calcContentBoxHeight(result);    } else if (cb->isRenderView() || (cb->isBody() && style()->htmlHacks()) || isPositionedWithSpecifiedHeight) {        // Don't allow this to affect the block' height() member variable, since this        // can get called while the block is still laying out its kids.        int oldHeight = cb->height();        cb->calcHeight();        result = cb->contentHeight();        cb->setHeight(oldHeight);    } else if (cb->isRoot() && isPositioned())        // Match the positioned objects behavior, which is that positioned objects will fill their viewport        // always.  Note we could only hit this case by recurring into calcPercentageHeight on a positioned containing block.        result = cb->calcContentBoxHeight(cb->availableHeight());    if (result != -1) {        result = height.calcValue(result);        if (includeBorderPadding) {            // It is necessary to use the border-box to match WinIE's broken            // box model.  This is essential for sizing inside            // table cells using percentage heights.            result -= (borderTop() + paddingTop() + borderBottom() + paddingBottom());            result = max(0, result);        }    }    return result;}int RenderBox::calcReplacedWidth(bool includeMaxWidth) const{    int width = calcReplacedWidthUsing(style()->width());    int minW = calcReplacedWidthUsing(style()->minWidth());    int maxW = !includeMaxWidth || style()->maxWidth().isUndefined() ? width : calcReplacedWidthUsing(style()->maxWidth());    return max(minW, min(width, maxW));}int RenderBox::calcReplacedWidthUsing(Length width) const{    switch (width.type()) {        case Fixed:            return calcContentBoxWidth(width.value());        case Percent: {            const int cw = isPositioned() ? containingBlockWidthForPositioned(toRenderBoxModelObject(container())) : containingBlockWidthForContent();            if (cw > 0)                return calcContentBoxWidth(width.calcMinValue(cw));        }        // fall through        default:            return intrinsicSize().width();     } }int RenderBox::calcReplacedHeight() const{    int height = calcReplacedHeightUsing(style()->height());    int minH = calcReplacedHeightUsing(style()->minHeight());    int maxH = style()->maxHeight().isUndefined() ? height : calcReplacedHeightUsing(style()->maxHeight());    return max(minH, min(height, maxH));}int RenderBox::calcReplacedHeightUsing(Length height) const{    switch (height.type()) {        case Fixed:            return calcContentBoxHeight(height.value());        case Percent:        {            RenderObject* cb = isPositioned() ? container() : containingBlock();            while (cb->isAnonymous()) {                cb = cb->containingBlock();                toRenderBlock(cb)->addPercentHeightDescendant(const_cast<RenderBox*>(this));            }            if (cb->isPositioned() && cb->style()->height().isAuto() && !(cb->style()->top().isAuto() || cb->style()->bottom().isAuto())) {                ASSERT(cb->isRenderBlock());                RenderBlock* block = toRenderBlock(cb);                int oldHeight = block->height();                block->calcHeight();                int newHeight = block->calcContentBoxHeight(block->contentHeight());                block->setHeight(oldHeight);                return calcContentBoxHeight(height.calcValue(newHeight));            }                        int availableHeight = isPositioned() ? containingBlockHeightForPositioned(toRenderBoxModelObject(cb)) : toRenderBox(cb)->availableHeight();            // It is necessary to use the border-box to match WinIE's broken            // box model.  This is essential for sizing inside            // table cells using percentage heights.            if (cb->isTableCell() && (cb->style()->height().isAuto() || cb->style()->height().isPercent())) {                // Don't let table cells squeeze percent-height replaced elements                // <http://bugs.webkit.org/show_bug.cgi?id=15359>                availableHeight = max(availableHeight, intrinsicSize().height());                return height.calcValue(availableHeight - (borderTop() + borderBottom()                    + paddingTop() + paddingBottom()));            }            return calcContentBoxHeight(height.calcValue(availableHeight));        }        default:            return intrinsicSize().height();    }}int RenderBox::availableHeight() const{    return availableHeightUsing(style()->height());}int RenderBox::availableHeightUsing(const Length& h) const{    if (h.isFixed())        return calcContentBoxHeight(h.value());    if (isRenderView())        return toRenderView(this)->frameView()->visibleHeight();    // We need to stop here, since we don't want to increase the height of the table    // artificially.  We're going to rely on this cell getting expanded to some new    // height, and then when we lay out again we'll use the calculation below.    if (isTableCell() && (h.isAuto() || h.isPercent()))        return overrideSize() - (borderLeft() + borderRight() + paddingLeft() + paddingRight());    if (h.isPercent())       return calcContentBoxHeight(h.calcValue(containingBlock()->availableHeight()));    if (isRenderBlock() && isPositioned() && style()->height().isAuto() && !(style()->top().isAuto() || style()->bottom().isAuto())) {        RenderBlock* block = const_cast<RenderBlock*>(toRenderBlock(this));        int oldHeight = block->height();        block->calcHeight();        int newHeight = block->calcContentBoxHeight(block->contentHeight());        block->setHeight(oldHeight);        return calcContentBoxHeight(newHeight);    }    return containingBlock()->availableHeight();}void RenderBox::calcVerticalMargins(){    if (isTableCell()) {        m_marginTop = 0;        m_marginBottom = 0;        return;    }    // margins are calculated with respect to the _width_ of    // the containing block (8.3)    int cw = containingBlock()->contentWidth();    m_marginTop = style()->marginTop().calcMinValue(cw);    m_marginBottom = style()->marginBottom().calcMinValue(cw);}int RenderBox::containingBlockWidthForPositioned(const RenderBoxModelObject* containingBlock) const{    if (containingBlock->isBox()) {        const RenderBox* containingBlockBox = toRenderBox(containingBlock);        return containingBlockBox->width() - containingBlockBox->borderLeft() - containingBlockBox->borderRight() - containingBlockBox->verticalScrollbarWidth();    }        ASSERT(containingBlock->isRenderInline() && containingBlock->isRelPositioned());    const RenderInline* flow = toRenderInline(containingBlock);    InlineFlowBox* first = flow->firstLineBox();    InlineFlowBox* last = flow->lastLineBox();    // If the containing block is empty, return a width of 0.    if (!first || !last)        return 0;    int fromLeft;    int fromRight;    if (containingBlock->style()->direction() == LTR) {        fromLeft = first->x() + first->borderLeft();        fromRight = last->x() + last->width() - last->borderRight();    } else {        fromRight = first->x() + first->width() - first->borderRight();        fromLeft = last->x() + last->borderLeft();    }    return max(0, (fromRight - fromLeft));}int RenderBox::containingBlockHeightForPositioned(const RenderBoxModelObject* containingBlock) const{       int heightResult = 0;    if (containingBlock->isBox())         heightResult = toRenderBox(containingBlock)->height();    else if (containingBlock->isRenderInline()) {        ASSERT(containingBlock->isRelPositioned());        heightResult = toRenderInline(containingBlock)->linesBoundingBox().height();    }    return heightResult - containingBlock->borderTop() - containingBlock->borderBottom();}void RenderBox::calcAbsoluteHorizontal(){    if (isReplaced()) {        calcAbsoluteHorizontalReplaced();        return;    }    // QUESTIONS    // FIXME 1: Which RenderObject's 'direction' property should used: the    // containing block (cb) as the spec seems to imply, the parent (parent()) as    // was previously done

⌨️ 快捷键说明

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