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

📄 render_object.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/**
 * This file is part of the html renderer for KDE.
 *
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004 Apple Computer, Inc.
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */

#include "rendering/render_object.h"
#include "rendering/render_table.h"
#include "rendering/render_text.h"
#include "rendering/render_line.h"
#include "rendering/render_list.h"
#include "rendering/render_canvas.h"
#include "xml/dom_elementimpl.h"
#include "xml/dom2_eventsimpl.h"
#include "xml/dom_docimpl.h"
#include "xml/dom_position.h"
#include "css/cssstyleselector.h"
#include "misc/htmlhashes.h"
#include <kdebug.h>
#include <qpainter.h>
#include "khtmlview.h"
#include "khtml_part.h"
#include "render_arena.h"
#include "render_inline.h"
#include "render_block.h"
#include "render_flexbox.h"

#if APPLE_CHANGES
// For accessibility
#include "KWQAccObjectCache.h"
#endif
#include <assert.h>
using namespace DOM;
using namespace khtml;

#if !NDEBUG || NOKIA_CHANGES
static void *baseOfRenderObjectBeingDeleted;
#endif

void* RenderObject::operator new(size_t sz, RenderArena* renderArena) throw()
{
    return renderArena->allocate(sz);
}

void RenderObject::operator delete(void* ptr, size_t sz)
{
#if NOKIA_CHANGES
    baseOfRenderObjectBeingDeleted = ptr;
#else
    assert(baseOfRenderObjectBeingDeleted == ptr);
#endif
    // Stash size where detach can find it.
    *(size_t *)ptr = sz;
}

RenderObject *RenderObject::createObject(DOM::NodeImpl* node,  RenderStyle* style)
{
    RenderObject *o = 0;
    RenderArena* arena = node->getDocument()->renderArena();
    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:
        //kdDebug( 6040 ) << "creating RenderTable" << endl;
        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;
}

RenderObject::RenderObject(DOM::NodeImpl* node)
    : CachedObjectClient(),
m_style( 0 ),
m_node( node ),
m_parent( 0 ),
m_previous( 0 ),
m_next( 0 ),
m_verticalPosition( PositionUndefined ),
m_needsLayout( false ),
m_normalChildNeedsLayout( false ),
m_posChildNeedsLayout( false ),
m_minMaxKnown( false ),
m_floating( false ),

m_positioned( false ),
m_relPositioned( false ),
m_paintBackground( false ),

m_isAnonymous( node == node->getDocument() ),
m_recalcMinMax( false ),
m_isText( false ),
m_inline( true ),

m_replaced( false ),
m_mouseInside( false ),
m_isDragging( false ),
m_hasOverflowClip(false)
{
}

RenderObject::~RenderObject()
{
}

bool RenderObject::hasAncestor(const RenderObject *obj) const
{
    for (const RenderObject *r = this; r; r = r->m_parent)
        if (r == obj)
            return true;
    return false;
}

bool RenderObject::isRoot() const
{
    return element() && element()->renderer() == this &&
           element()->getDocument()->documentElement() == element();
}

bool RenderObject::isBody() const
{
    return element() && element()->renderer() == this && element()->id() == ID_BODY;
}

bool RenderObject::isHR() const
{
    return element() && element()->id() == ID_HR;
}

bool RenderObject::isHTMLMarquee() const
{
    return element() && element()->renderer() == this && element()->id() == ID_MARQUEE;
}

bool RenderObject::canHaveChildren() const
{
    return false;
}

RenderFlow* RenderObject::continuation() const
{
    return 0;
}

bool RenderObject::isInlineContinuation() const
{
    return false;
}

void RenderObject::addChild(RenderObject* , RenderObject *)
{
    KHTMLAssert(0);
}

RenderObject* RenderObject::removeChildNode(RenderObject* )
{
    KHTMLAssert(0);
    return 0;
}

void RenderObject::removeChild(RenderObject* )
{
    KHTMLAssert(0);
}

void RenderObject::appendChildNode(RenderObject*)
{
    KHTMLAssert(0);
}

void RenderObject::insertChildNode(RenderObject*, RenderObject*)
{
    KHTMLAssert(0);
}

RenderObject *RenderObject::nextRenderer() const
{
    if (firstChild())
        return firstChild();
    else if (nextSibling())
        return nextSibling();
    else {
        const RenderObject *r = this;
        while (r && !r->nextSibling())
            r = r->parent();
        if (r)
            return r->nextSibling();
    }
    return 0;
}

RenderObject *RenderObject::previousRenderer() const
{
    if (previousSibling()) {
        RenderObject *r = previousSibling();
        while (r->lastChild())
            r = r->lastChild();
        return r;
    }
    else if (parent()) {
        return parent();
    }
    else {
        return 0;
    }
}

bool RenderObject::isEditable() const
{
    RenderText *textRenderer = 0;
    if (isText()) {
        textRenderer = static_cast<RenderText *>(const_cast<RenderObject *>(this));
    }

    return style()->visibility() == VISIBLE &&
        element() && element()->isContentEditable() &&
        ((isBlockFlow() && !firstChild()) ||
        isReplaced() ||
        isBR() ||
        (textRenderer && textRenderer->firstTextBox()));
}

RenderObject *RenderObject::nextEditable() const
{
    RenderObject *r = const_cast<RenderObject *>(this);
    RenderObject *n = firstChild();
    if (n) {
        while (n) {
            r = n;
            n = n->firstChild();
        }
        if (r->isEditable())
            return r;
        else
            return r->nextEditable();
    }
    n = r->nextSibling();
    if (n) {
        r = n;
        while (n) {
            r = n;
            n = n->firstChild();
        }
        if (r->isEditable())
            return r;
        else
            return r->nextEditable();
    }
    n = r->parent();
    while (n) {
        r = n;
        n = r->nextSibling();
        if (n) {
            r = n;
            n = r->firstChild();
            while (n) {
                r = n;
                n = n->firstChild();
            }
            if (r->isEditable())
                return r;
            else
                return r->nextEditable();
        }
        n = r->parent();
    }
    return 0;
}

RenderObject *RenderObject::previousEditable() const
{
    RenderObject *r = const_cast<RenderObject *>(this);
    RenderObject *n = firstChild();
    if (n) {
        while (n) {
            r = n;
            n = n->lastChild();
        }
        if (r->isEditable())
            return r;
        else
            return r->previousEditable();
    }
    n = r->previousSibling();
    if (n) {
        r = n;
        while (n) {
            r = n;
            n = n->lastChild();
        }
        if (r->isEditable())
            return r;
        else
            return r->previousEditable();
    }
    n = r->parent();
    while (n) {
        r = n;
        n = r->previousSibling();
        if (n) {
            r = n;
            n = r->lastChild();
            while (n) {
                r = n;
                n = n->lastChild();
            }
            if (r->isEditable())
                return r;
            else
                return r->previousEditable();
        }
        n = r->parent();
    }
    return 0;
}

RenderObject *RenderObject::firstLeafChild() const
{
    RenderObject *r = firstChild();
    while (r) {
        RenderObject *n = 0;
        n = r->firstChild();
        if (!n)
            break;
        r = n;
    }
    return r;
}

RenderObject *RenderObject::lastLeafChild() const
{
    RenderObject *r = lastChild();
    while (r) {
        RenderObject *n = 0;
        n = r->lastChild();
        if (!n)
            break;
        r = n;
    }
    return r;
}

static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject*& newObject,
                      RenderLayer*& beforeChild)
{
    if (obj->layer()) {
        if (!beforeChild && newObject) {
            // We need to figure out the layer that follows newObject.  We only do
            // this the first time we find a child layer, and then we update the
            // pointer values for newObject and beforeChild used by everyone else.
            beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject);
            newObject = 0;
        }
        parentLayer->addChild(obj->layer(), beforeChild);
        return;
    }

⌨️ 快捷键说明

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