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

📄 renderobject.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) *           (C) 2000 Dirk Mueller (mueller@kde.org) *           (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) * Copyright (C) 2004, 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 "RenderObject.h"#include "AXObjectCache.h"#include "CSSStyleSelector.h"#include "FloatQuad.h"#include "Frame.h"#include "FrameView.h"#include "GraphicsContext.h"#include "HTMLNames.h"#include "HitTestResult.h"#include "Page.h"#include "RenderArena.h"#include "RenderCounter.h"#include "RenderFlexibleBox.h"#include "RenderImageGeneratedContent.h"#include "RenderInline.h"#include "RenderListItem.h"#include "RenderTableCell.h"#include "RenderTableCol.h"#include "RenderTableRow.h"#include "RenderTheme.h"#include "RenderView.h"#include "TransformState.h"#include <algorithm>#include <stdio.h>#include <wtf/RefCountedLeakCounter.h>#include <wtf/UnusedParam.h>#if USE(ACCELERATED_COMPOSITING)#include "RenderLayerCompositor.h"#endif#if ENABLE(WML)#include "WMLNames.h"#endifusing namespace std;namespace WebCore {using namespace HTMLNames;#ifndef NDEBUGstatic void* baseOfRenderObjectBeingDeleted;#endifbool RenderObject::s_affectsParentBlock = false;void* RenderObject::operator new(size_t sz, RenderArena* renderArena) throw(){    return renderArena->allocate(sz);}void RenderObject::operator delete(void* ptr, size_t sz){    ASSERT(baseOfRenderObjectBeingDeleted == ptr);    // Stash size where destroy can find it.    *(size_t *)ptr = sz;}RenderObject* RenderObject::createObject(Node* node, RenderStyle* style){    Document* doc = node->document();    RenderArena* arena = doc->renderArena();    // Minimal support for content properties replacing an entire element.    // Works only if we have exactly one piece of content and it's a URL.    // Otherwise acts as if we didn't support this feature.    const ContentData* contentData = style->contentData();    if (contentData && !contentData->m_next && contentData->m_type == CONTENT_OBJECT && doc != node) {        RenderImageGeneratedContent* image = new (arena) RenderImageGeneratedContent(node);        image->setStyle(style);        if (StyleImage* styleImage = contentData->m_content.m_image)            image->setStyleImage(styleImage);        return image;    }    RenderObject* o = 0;    switch (style->display()) {        case NONE:            break;        case INLINE:            o = new (arena) RenderInline(node);            break;        case BLOCK:            o = new (arena) RenderBlock(node);            break;        case INLINE_BLOCK:            o = new (arena) RenderBlock(node);            break;        case LIST_ITEM:            o = new (arena) RenderListItem(node);            break;        case RUN_IN:        case COMPACT:            o = new (arena) RenderBlock(node);            break;        case TABLE:        case INLINE_TABLE:            o = new (arena) RenderTable(node);            break;        case TABLE_ROW_GROUP:        case TABLE_HEADER_GROUP:        case TABLE_FOOTER_GROUP:            o = new (arena) RenderTableSection(node);            break;        case TABLE_ROW:            o = new (arena) RenderTableRow(node);            break;        case TABLE_COLUMN_GROUP:        case TABLE_COLUMN:            o = new (arena) RenderTableCol(node);            break;        case TABLE_CELL:            o = new (arena) RenderTableCell(node);            break;        case TABLE_CAPTION:            o = new (arena) RenderBlock(node);            break;        case BOX:        case INLINE_BOX:            o = new (arena) RenderFlexibleBox(node);            break;    }    return o;}#ifndef NDEBUG static WTF::RefCountedLeakCounter renderObjectCounter("RenderObject");#endifRenderObject::RenderObject(Node* node)    : CachedResourceClient()    , m_style(0)    , m_node(node)    , m_parent(0)    , m_previous(0)    , m_next(0)#ifndef NDEBUG    , m_hasAXObject(false)    , m_setNeedsLayoutForbidden(false)#endif    , m_needsLayout(false)    , m_needsPositionedMovementLayout(false)    , m_normalChildNeedsLayout(false)    , m_posChildNeedsLayout(false)    , m_prefWidthsDirty(false)    , m_floating(false)    , m_positioned(false)    , m_relPositioned(false)    , m_paintBackground(false)    , m_isAnonymous(node == node->document())    , m_isText(false)    , m_isBox(false)    , m_inline(true)    , m_replaced(false)    , m_isDragging(false)    , m_hasLayer(false)    , m_hasOverflowClip(false)    , m_hasTransform(false)    , m_hasReflection(false)    , m_hasOverrideSize(false)    , m_hasCounterNodeMap(false)    , m_everHadLayout(false)    , m_childrenInline(false)    , m_topMarginQuirk(false)     , m_bottomMarginQuirk(false)    , m_hasMarkupTruncation(false)    , m_selectionState(SelectionNone)    , m_hasColumns(false)    , m_cellWidthChanged(false)    , m_replacedHasOverflow(false){#ifndef NDEBUG    renderObjectCounter.increment();#endif    ASSERT(node);}RenderObject::~RenderObject(){    ASSERT(!node() || documentBeingDestroyed() || !document()->frame()->view() || document()->frame()->view()->layoutRoot() != this);#ifndef NDEBUG    ASSERT(!m_hasAXObject);    renderObjectCounter.decrement();#endif}bool RenderObject::isDescendantOf(const RenderObject* obj) const{    for (const RenderObject* r = this; r; r = r->m_parent) {        if (r == obj)            return true;    }    return false;}bool RenderObject::isBody() const{    return node() && node()->hasTagName(bodyTag);}bool RenderObject::isHR() const{    return node() && node()->hasTagName(hrTag);}bool RenderObject::isHTMLMarquee() const{    return node() && node()->renderer() == this && node()->hasTagName(marqueeTag);}static void updateListMarkerNumbers(RenderObject* child){    for (RenderObject* r = child; r; r = r->nextSibling())        if (r->isListItem())            static_cast<RenderListItem*>(r)->updateValue();}void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild){    RenderObjectChildList* children = virtualChildren();    ASSERT(children);    if (!children)        return;    bool needsTable = false;    if (newChild->isListItem())        updateListMarkerNumbers(beforeChild ? beforeChild : children->lastChild());    else if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)        needsTable = !isTable();    else if (newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION)        needsTable = !isTable();    else if (newChild->isTableSection())        needsTable = !isTable();    else if (newChild->isTableRow())        needsTable = !isTableSection();    else if (newChild->isTableCell()) {        needsTable = !isTableRow();        // I'm not 100% sure this is the best way to fix this, but without this        // change we recurse infinitely when trying to render the CSS2 test page:        // http://www.bath.ac.uk/%7Epy8ieh/internet/eviltests/htmlbodyheadrendering2.html.        // See Radar 2925291.        if (needsTable && isTableCell() && !children->firstChild() && !newChild->isTableCell())            needsTable = false;    }    if (needsTable) {        RenderTable* table;        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : children->lastChild();        if (afterChild && afterChild->isAnonymous() && afterChild->isTable())            table = static_cast<RenderTable*>(afterChild);        else {            table = new (renderArena()) RenderTable(document() /* is anonymous */);            RefPtr<RenderStyle> newStyle = RenderStyle::create();            newStyle->inheritFrom(style());            newStyle->setDisplay(TABLE);            table->setStyle(newStyle.release());            addChild(table, beforeChild);        }        table->addChild(newChild);    } else {        // Just add it...        children->insertChildNode(this, newChild, beforeChild);    }        if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) {        RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalText();        if (textToTransform)            toRenderText(newChild)->setText(textToTransform.release(), true);    }}void RenderObject::removeChild(RenderObject* oldChild){    RenderObjectChildList* children = virtualChildren();    ASSERT(children);    if (!children)        return;    // We do this here instead of in removeChildNode, since the only extremely low-level uses of remove/appendChildNode    // cannot affect the positioned object list, and the floating object list is irrelevant (since the list gets cleared on    // layout anyway).    if (oldChild->isFloatingOrPositioned())        toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();            children->removeChildNode(this, oldChild);}RenderObject* RenderObject::nextInPreOrder() const{    if (RenderObject* o = firstChild())        return o;    return nextInPreOrderAfterChildren();}RenderObject* RenderObject::nextInPreOrderAfterChildren() const{    RenderObject* o;    if (!(o = nextSibling())) {        o = parent();        while (o && !o->nextSibling())            o = o->parent();        if (o)            o = o->nextSibling();    }    return o;}RenderObject* RenderObject::nextInPreOrder(RenderObject* stayWithin) const{    if (RenderObject* o = firstChild())        return o;    return nextInPreOrderAfterChildren(stayWithin);}RenderObject* RenderObject::nextInPreOrderAfterChildren(RenderObject* stayWithin) const{    if (this == stayWithin)        return 0;

⌨️ 快捷键说明

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