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

📄 renderbox.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
void RenderBox::positionLineBox(InlineBox* box){    if (isPositioned()) {        // Cache the x position only if we were an INLINE type originally.        bool wasInline = style()->isOriginalDisplayInlineType();        if (wasInline && style()->hasStaticX()) {            // The value is cached in the xPos of the box.  We only need this value if            // our object was inline originally, since otherwise it would have ended up underneath            // the inlines.            layer()->setStaticX(box->x());            setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.        } else if (!wasInline && style()->hasStaticY()) {            // Our object was a block originally, so we make our normal flow position be            // just below the line box (as though all the inlines that came before us got            // wrapped in an anonymous block, which is what would have happened had we been            // in flow).  This value was cached in the y() of the box.            layer()->setStaticY(box->y());            setChildNeedsLayout(true, false); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.        }        // Nuke the box.        box->remove();        box->destroy(renderArena());    } else if (isReplaced()) {        setLocation(box->x(), box->y());        m_inlineBoxWrapper = box;    }}void RenderBox::deleteLineBoxWrapper(){    if (m_inlineBoxWrapper) {        if (!documentBeingDestroyed())            m_inlineBoxWrapper->remove();        m_inlineBoxWrapper->destroy(renderArena());        m_inlineBoxWrapper = 0;    }}IntRect RenderBox::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer){    if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())        return IntRect();    IntRect r = overflowRect(false);    RenderView* v = view();    if (v) {        // FIXME: layoutDelta needs to be applied in parts before/after transforms and        // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308        r.move(v->layoutDelta());    }        if (style()) {        if (style()->hasAppearance())            // The theme may wish to inflate the rect used when repainting.            theme()->adjustRepaintRect(this, r);        // We have to use maximalOutlineSize() because a child might have an outline        // that projects outside of our overflowRect.        if (v) {            ASSERT(style()->outlineSize() <= v->maximalOutlineSize());            r.inflate(v->maximalOutlineSize());        }    }    computeRectForRepaint(repaintContainer, r);    return r;}void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed){    if (RenderView* v = view()) {        // LayoutState is only valid for root-relative repainting        if (v->layoutStateEnabled() && !repaintContainer) {            LayoutState* layoutState = v->layoutState();            if (style()->position() == RelativePosition && layer())                rect.move(layer()->relativePositionOffset());            rect.move(x(), y());            rect.move(layoutState->m_offset);            if (layoutState->m_clipped)                rect.intersect(layoutState->m_clipRect);            return;        }    }    if (hasReflection())        rect.unite(reflectedRect(rect));    if (repaintContainer == this)        return;    RenderObject* o = container();    if (!o)        return;    IntPoint topLeft = rect.location();    topLeft.move(x(), y());    if (style()->position() == FixedPosition)        fixed = true;    if (o->isBlockFlow() && style()->position() != AbsolutePosition && style()->position() != FixedPosition) {        RenderBlock* cb = toRenderBlock(o);        if (cb->hasColumns()) {            IntRect repaintRect(topLeft, rect.size());            cb->adjustRectForColumns(repaintRect);            topLeft = repaintRect.location();            rect = repaintRect;        }    }    // We are now in our parent container's coordinate space.  Apply our transform to obtain a bounding box    // in the parent's coordinate space that encloses us.    if (layer() && layer()->transform()) {        fixed = false;        rect = layer()->transform()->mapRect(rect);        // FIXME: this clobbers topLeft adjustment done for multicol above        topLeft = rect.location();        topLeft.move(x(), y());    }    if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())        topLeft += toRenderInline(o)->relativePositionedInlineOffset(this);    else if (style()->position() == RelativePosition && layer()) {        // Apply the relative position offset when invalidating a rectangle.  The layer        // is translated, but the render box isn't, so we need to do this to get the        // right dirty rect.  Since this is called from RenderObject::setStyle, the relative position        // flag on the RenderObject has been cleared, so use the one on the style().        topLeft += layer()->relativePositionOffset();    }        // FIXME: We ignore the lightweight clipping rect that controls use, since if |o| is in mid-layout,    // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer.    if (o->hasOverflowClip()) {        RenderBox* containerBox = toRenderBox(o);        // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the        // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint        // anyway if its size does change.        topLeft -= containerBox->layer()->scrolledContentOffset(); // For overflow:auto/scroll/hidden.        IntRect repaintRect(topLeft, rect.size());        IntRect boxRect(0, 0, containerBox->layer()->width(), containerBox->layer()->height());        rect = intersection(repaintRect, boxRect);        if (rect.isEmpty())            return;    } else        rect.setLocation(topLeft);        o->computeRectForRepaint(repaintContainer, rect, fixed);}void RenderBox::repaintDuringLayoutIfMoved(const IntRect& rect){    int newX = x();    int newY = y();    int newWidth = width();    int newHeight = height();    if (rect.x() != newX || rect.y() != newY) {        // The child moved.  Invalidate the object's old and new positions.  We have to do this        // since the object may not have gotten a layout.        m_frameRect = rect;        repaint();        repaintOverhangingFloats(true);        m_frameRect = IntRect(newX, newY, newWidth, newHeight);        repaint();        repaintOverhangingFloats(true);    }}void RenderBox::calcWidth(){    if (isPositioned()) {        calcAbsoluteHorizontal();        return;    }    // If layout is limited to a subtree, the subtree root's width does not change.    if (node() && view()->frameView() && view()->frameView()->layoutRoot(true) == this)        return;    // The parent box is flexing us, so it has increased or decreased our    // width.  Use the width from the style context.    if (hasOverrideSize() &&  parent()->style()->boxOrient() == HORIZONTAL            && parent()->isFlexibleBox() && parent()->isFlexingChildren()) {        setWidth(overrideSize());        return;    }    bool inVerticalBox = parent()->isFlexibleBox() && (parent()->style()->boxOrient() == VERTICAL);    bool stretching = (parent()->style()->boxAlign() == BSTRETCH);    bool treatAsReplaced = shouldCalculateSizeAsReplaced() && (!inVerticalBox || !stretching);    Length w = (treatAsReplaced) ? Length(calcReplacedWidth(), Fixed) : style()->width();    RenderBlock* cb = containingBlock();    int containerWidth = max(0, containingBlockWidthForContent());    Length marginLeft = style()->marginLeft();    Length marginRight = style()->marginRight();    if (isInline() && !isInlineBlockOrInlineTable()) {        // just calculate margins        m_marginLeft = marginLeft.calcMinValue(containerWidth);        m_marginRight = marginRight.calcMinValue(containerWidth);        if (treatAsReplaced)            setWidth(max(w.value() + borderLeft() + borderRight() + paddingLeft() + paddingRight(), minPrefWidth()));        return;    }    // Width calculations    if (treatAsReplaced)        setWidth(w.value() + borderLeft() + borderRight() + paddingLeft() + paddingRight());    else {        // Calculate Width        setWidth(calcWidthUsing(Width, containerWidth));        // Calculate MaxWidth        if (!style()->maxWidth().isUndefined()) {            int maxW = calcWidthUsing(MaxWidth, containerWidth);            if (width() > maxW) {                setWidth(maxW);                w = style()->maxWidth();            }        }        // Calculate MinWidth        int minW = calcWidthUsing(MinWidth, containerWidth);        if (width() < minW) {            setWidth(minW);            w = style()->minWidth();        }    }    if (stretchesToMinIntrinsicWidth()) {        setWidth(max(width(), minPrefWidth()));        w = Length(width(), Fixed);    }    // Margin calculations    if (w.isAuto()) {        m_marginLeft = marginLeft.calcMinValue(containerWidth);        m_marginRight = marginRight.calcMinValue(containerWidth);    } else {        m_marginLeft = 0;        m_marginRight = 0;        calcHorizontalMargins(marginLeft, marginRight, containerWidth);    }    if (containerWidth && containerWidth != (width() + m_marginLeft + m_marginRight)            && !isFloating() && !isInline() && !cb->isFlexibleBox()) {        if (cb->style()->direction() == LTR)            m_marginRight = containerWidth - width() - m_marginLeft;        else            m_marginLeft = containerWidth - width() - m_marginRight;    }}int RenderBox::calcWidthUsing(WidthType widthType, int cw){    int widthResult = width();    Length w;    if (widthType == Width)        w = style()->width();    else if (widthType == MinWidth)        w = style()->minWidth();    else        w = style()->maxWidth();    if (w.isIntrinsicOrAuto()) {        int marginLeft = style()->marginLeft().calcMinValue(cw);        int marginRight = style()->marginRight().calcMinValue(cw);        if (cw)            widthResult = cw - marginLeft - marginRight;        if (sizesToIntrinsicWidth(widthType)) {            widthResult = max(widthResult, minPrefWidth());            widthResult = min(widthResult, maxPrefWidth());        }    } else        widthResult = calcBorderBoxWidth(w.calcValue(cw));    return widthResult;}bool RenderBox::sizesToIntrinsicWidth(WidthType widthType) const{    // Marquees in WinIE are like a mixture of blocks and inline-blocks.  They size as though they're blocks,    // but they allow text to sit on the same line as the marquee.    if (isFloating() || (isInlineBlockOrInlineTable() && !isHTMLMarquee()))        return true;    // This code may look a bit strange.  Basically width:intrinsic should clamp the size when testing both    // min-width and width.  max-width is only clamped if it is also intrinsic.    Length width = (widthType == MaxWidth) ? style()->maxWidth() : style()->width();    if (width.type() == Intrinsic)        return true;    // Children of a horizontal marquee do not fill the container by default.    // FIXME: Need to deal with MAUTO value properly.  It could be vertical.    if (parent()->style()->overflowX() == OMARQUEE) {        EMarqueeDirection dir = parent()->style()->marqueeDirection();        if (dir == MAUTO || dir == MFORWARD || dir == MBACKWARD || dir == MLEFT || dir == MRIGHT)            return true;    }    // Flexible horizontal boxes lay out children at their intrinsic widths.  Also vertical boxes    // that don't stretch their kids lay out their children at their intrinsic widths.    if (parent()->isFlexibleBox()            && (parent()->style()->boxOrient() == HORIZONTAL || parent()->style()->boxAlign() != BSTRETCH))        return true;    return false;}void RenderBox::calcHorizontalMargins(const Length& marginLeft, const Length& marginRight, int containerWidth){    if (isFloating() || isInline()) {        // Inline blocks/tables and floats don't have their margins increased.        m_marginLeft = marginLeft.calcMinValue(containerWidth);        m_marginRight = marginRight.calcMinValue(containerWidth);        return;    }    if ((marginLeft.isAuto() && marginRight.isAuto() && width() < containerWidth)            || (!marginLeft.isAuto() && !marginRight.isAuto() && containingBlock()->style()->textAlign() == WEBKIT_CENTER)) {        m_marginLeft = max(0, (containerWidth - width()) / 2);        m_marginRight = containerWidth - width() - m_marginLeft;    } else if ((marginRight.isAuto() && width() < containerWidth)            || (!marginLeft.isAuto() && containingBlock()->style()->direction() == RTL && containingBlock()->style()->textAlign() == WEBKIT_LEFT)) {        m_marginLeft = marginLeft.calcValue(containerWidth);        m_marginRight = containerWidth - width() - m_marginLeft;    } else if ((marginLeft.isAuto() && width() < containerWidth)            || (!marginRight.isAuto() && containingBlock()->style()->direction() == LTR && containingBlock()->style()->textAlign() == WEBKIT_RIGHT)) {        m_marginRight = marginRight.calcValue(containerWidth);        m_marginLeft = containerWidth - width() - m_marginRight;    } else {        // This makes auto margins 0 if we failed a width() < containerWidth test above (css2.1, 10.3.3).        m_marginLeft = marginLeft.calcMinValue(containerWidth);        m_marginRight = marginRight.calcMinValue(containerWidth);    }}void RenderBox::calcHeight(){    // Cell height is managed by the table and inline non-replaced elements do not support a height property.

⌨️ 快捷键说明

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