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

📄 renderbox.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) *           (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) *           (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */#include "config.h"#include "RenderBox.h"#include "CachedImage.h"#include "ChromeClient.h"#include "Document.h"#include "FrameView.h"#include "GraphicsContext.h"#include "htmlediting.h"#include "HTMLElement.h"#include "HTMLNames.h"#include "ImageBuffer.h"#include "FloatQuad.h"#include "Frame.h"#include "Page.h"#include "RenderArena.h"#include "RenderFlexibleBox.h"#include "RenderInline.h"#include "RenderLayer.h"#include "RenderTableCell.h"#include "RenderTheme.h"#include "RenderView.h"#include "TransformState.h"#include <algorithm>#include <math.h>#if ENABLE(WML)#include "WMLNames.h"#endifusing namespace std;namespace WebCore {using namespace HTMLNames;// Used by flexible boxes when flexing this element.typedef WTF::HashMap<const RenderBox*, int> OverrideSizeMap;static OverrideSizeMap* gOverrideSizeMap = 0;bool RenderBox::s_hadOverflowClip = false;RenderBox::RenderBox(Node* node)    : RenderBoxModelObject(node)    , m_marginLeft(0)    , m_marginRight(0)    , m_marginTop(0)    , m_marginBottom(0)    , m_minPrefWidth(-1)    , m_maxPrefWidth(-1)    , m_inlineBoxWrapper(0){    setIsBox();}RenderBox::~RenderBox(){}void RenderBox::destroy(){    // A lot of the code in this function is just pasted into    // RenderWidget::destroy. If anything in this function changes,    // be sure to fix RenderWidget::destroy() as well.    if (hasOverrideSize())        gOverrideSizeMap->remove(this);    if (style() && (style()->height().isPercent() || style()->minHeight().isPercent() || style()->maxHeight().isPercent()))        RenderBlock::removePercentHeightDescendant(this);    RenderBoxModelObject::destroy();}void RenderBox::removeFloatingOrPositionedChildFromBlockLists(){    ASSERT(isFloatingOrPositioned());    if (documentBeingDestroyed())        return;    if (isFloating()) {        RenderBlock* outermostBlock = containingBlock();        for (RenderBlock* p = outermostBlock; p && !p->isRenderView(); p = p->containingBlock()) {            if (p->containsFloat(this))                outermostBlock = p;        }        if (outermostBlock)            outermostBlock->markAllDescendantsWithFloatsForLayout(this, false);    }    if (isPositioned()) {        RenderObject* p;        for (p = parent(); p; p = p->parent()) {            if (p->isRenderBlock())                toRenderBlock(p)->removePositionedObject(this);        }    }}void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle){    s_hadOverflowClip = hasOverflowClip();    if (style()) {        // The background of the root element or the body element could propagate up to        // the canvas.  Just dirty the entire canvas when our style changes substantially.        if (diff >= StyleDifferenceRepaint && node() &&                (node()->hasTagName(htmlTag) || node()->hasTagName(bodyTag)))            view()->repaint();        else if (parent() && !isText()) {            // Do a repaint with the old style first, e.g., for example if we go from            // having an outline to not having an outline.            if (diff == StyleDifferenceRepaintLayer) {                layer()->repaintIncludingDescendants();                if (!(style()->clip() == newStyle->clip()))                    layer()->clearClipRectsIncludingDescendants();            } else if (diff == StyleDifferenceRepaint || newStyle->outlineSize() < style()->outlineSize())                repaint();        }        if (diff == StyleDifferenceLayout) {            // When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could            // end up being destroyed.            if (hasLayer()) {                if (style()->position() != newStyle->position() ||                    style()->zIndex() != newStyle->zIndex() ||                    style()->hasAutoZIndex() != newStyle->hasAutoZIndex() ||                    !(style()->clip() == newStyle->clip()) ||                    style()->hasClip() != newStyle->hasClip() ||                    style()->opacity() != newStyle->opacity() ||                    style()->transform() != newStyle->transform())                layer()->repaintIncludingDescendants();            } else if (newStyle->hasTransform() || newStyle->opacity() < 1) {                // If we don't have a layer yet, but we are going to get one because of transform or opacity,                //  then we need to repaint the old position of the object.                repaint();            }                    // When a layout hint happens and an object's position style changes, we have to do a layout            // to dirty the render tree using the old position value now.            if (parent() && style()->position() != newStyle->position()) {                markContainingBlocksForLayout();                if (style()->position() == StaticPosition)                    repaint();                if (isFloating() && !isPositioned() && (newStyle->position() == AbsolutePosition || newStyle->position() == FixedPosition))                    removeFloatingOrPositionedChildFromBlockLists();            }        }    }    RenderBoxModelObject::styleWillChange(diff, newStyle);}void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle){    RenderBoxModelObject::styleDidChange(diff, oldStyle);    if (needsLayout() && oldStyle && (oldStyle->height().isPercent() || oldStyle->minHeight().isPercent() || oldStyle->maxHeight().isPercent()))        RenderBlock::removePercentHeightDescendant(this);    // If our zoom factor changes and we have a defined scrollLeft/Top, we need to adjust that value into the    // new zoomed coordinate space.    if (hasOverflowClip() && oldStyle && style() && oldStyle->effectiveZoom() != style()->effectiveZoom()) {        int left = scrollLeft();        if (left) {            left = (left / oldStyle->effectiveZoom()) * style()->effectiveZoom();            setScrollLeft(left);        }        int top = scrollTop();        if (top) {            top = (top / oldStyle->effectiveZoom()) * style()->effectiveZoom();            setScrollTop(top);        }    }    // Set the text color if we're the body.    if (isBody())        document()->setTextColor(style()->color());}void RenderBox::updateBoxModelInfoFromStyle(){    RenderBoxModelObject::updateBoxModelInfoFromStyle();    bool isRootObject = isRoot();    bool isViewObject = isRenderView();    // The root and the RenderView always paint their backgrounds/borders.    if (isRootObject || isViewObject)        setHasBoxDecorations(true);    setPositioned(style()->position() == AbsolutePosition || style()->position() == FixedPosition);    setFloating(!isPositioned() && style()->isFloating());    // We also handle <body> and <html>, whose overflow applies to the viewport.    if (style()->overflowX() != OVISIBLE && !isRootObject && (isRenderBlock() || isTableRow() || isTableSection())) {        bool boxHasOverflowClip = true;        if (isBody()) {            // Overflow on the body can propagate to the viewport under the following conditions.            // (1) The root element is <html>.            // (2) We are the primary <body> (can be checked by looking at document.body).            // (3) The root element has visible overflow.            if (document()->documentElement()->hasTagName(htmlTag) &&                document()->body() == node() &&                document()->documentElement()->renderer()->style()->overflowX() == OVISIBLE)                boxHasOverflowClip = false;        }                // Check for overflow clip.        // It's sufficient to just check one direction, since it's illegal to have visible on only one overflow value.        if (boxHasOverflowClip) {            if (!s_hadOverflowClip)                // Erase the overflow                repaint();            setHasOverflowClip();        }    }    setHasTransform(style()->hasTransformRelatedProperty());    setHasReflection(style()->boxReflect());}void RenderBox::layout(){    ASSERT(needsLayout());    RenderObject* child = firstChild();    if (!child) {        setNeedsLayout(false);        return;    }    LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()));    while (child) {        child->layoutIfNeeded();        ASSERT(!child->needsLayout());        child = child->nextSibling();    }    statePusher.pop();    setNeedsLayout(false);}// More IE extensions.  clientWidth and clientHeight represent the interior of an object// excluding border and scrollbar.int RenderBox::clientWidth() const{    return width() - borderLeft() - borderRight() - verticalScrollbarWidth();}int RenderBox::clientHeight() const{    return height() - borderTop() - borderBottom() - horizontalScrollbarHeight();}// scrollWidth/scrollHeight will be the same as overflowWidth/overflowHeight unless the// object has overflow:hidden/scroll/auto specified and also has overflow.// FIXME: It's not completely clear how scrollWidth/Height should behave for // objects with visible overflow.int RenderBox::scrollWidth() const{    if (hasOverflowClip())        return layer()->scrollWidth();    return overflowWidth();}int RenderBox::scrollHeight() const{    if (hasOverflowClip())        return layer()->scrollHeight();    return overflowHeight();}int RenderBox::scrollLeft() const{    return hasOverflowClip() ? layer()->scrollXOffset() : 0;}int RenderBox::scrollTop() const{    return hasOverflowClip() ? layer()->scrollYOffset() : 0;}void RenderBox::setScrollLeft(int newLeft){    if (hasOverflowClip())        layer()->scrollToXOffset(newLeft);}void RenderBox::setScrollTop(int newTop){    if (hasOverflowClip())        layer()->scrollToYOffset(newTop);}void RenderBox::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool){    rects.append(IntRect(tx, ty, width(), height()));}void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool){    quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height())));}IntRect RenderBox::absoluteContentBox() const{    IntRect rect = contentBoxRect();    FloatPoint absPos = localToAbsolute(FloatPoint());    rect.move(absPos.x(), absPos.y());    return rect;}FloatQuad RenderBox::absoluteContentQuad() const{    IntRect rect = contentBoxRect();    return localToAbsoluteQuad(FloatRect(rect));}IntRect RenderBox::outlineBoundsForRepaint(RenderBoxModelObject* /*repaintContainer*/) const{    IntRect box = borderBoundingBox();    adjustRectForOutlineAndShadow(box);

⌨️ 快捷键说明

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