📄 render_object.cpp
字号:
/**
* 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 + -