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

📄 render_object.cpp

📁 monqueror一个很具有参考价值的源玛
💻 CPP
字号:
/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) * * 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. * * $Id: render_object.cpp,v 1.2 2002/01/28 04:31:02 leon Exp $ */#include <assert.h>#include "dom_nodeimpl.h"#include "render_interface.h"#include "mgcolor.h"#include "mgpen.h"#include "mgbrush.h"#include "mgsize.h"#include "mgrect.h"#include "mgfontmetrics.h"#include "mgpainter.h"#include "mghtml_part.h"#include "render_object.h"#include "render_box.h"#include "render_flow.h"#include "render_style.h"#include "render_table.h"#include "render_list.h"#include "render_style.h"#include "kdebug.h"using namespace DOM;using namespace khtml;RenderObject *RenderObject::createObject(DOM::NodeImpl *node){    RenderStyle *style = node->style();    RenderObject *o = 0;//fprintf(stderr,"createObject style->display:%d\n",style->display());		switch(style->display())    {    case INLINE:    case BLOCK:        o = new RenderFlow();        break;    case LIST_ITEM:        o = new RenderListItem();        break;    case RUN_IN:    case COMPACT:    case MARKER:        break;    case TABLE:    case INLINE_TABLE:        // ### set inline/block right        //kdDebug( 6040 ) << "creating RenderTable" << endl;        o = new RenderTable();        break;    case TABLE_ROW_GROUP:    case TABLE_HEADER_GROUP:    case TABLE_FOOTER_GROUP:        o = new RenderTableSection();        break;    case TABLE_ROW:        o = new RenderTableRow();        break;    case TABLE_COLUMN_GROUP:    case TABLE_COLUMN:        o = new RenderTableCol();        break;    case TABLE_CELL:        o = new RenderTableCell();        break;    case TABLE_CAPTION:        o = new RenderTableCaption();        break;    case NONE:        return 0;    }    if(o) o->setStyle(style);    return o;}RenderObject::RenderObject(){    m_style = 0;    m_part = NULL;    hasKeyboardFocus=DOM::ActivationOff;    m_layouted = false;    m_parsing = false;    m_minMaxKnown = false;    m_parent = 0;    m_previous = 0;    m_next = 0;    m_first = 0;    m_last = 0;    m_floating = false;    m_positioned = false;    m_relPositioned = false;    m_printSpecial = false;    m_containsPositioned = false;    m_isAnonymous = false;    m_isText = false;    m_inline = true;    m_replaced = false;    m_visible = true;    m_bgImage = 0;}RenderObject::~RenderObject(){    if(m_bgImage) m_bgImage->deref();	m_bgImage = 0;    //kdDebug( 6090 ) << "RenderObject::~RenderObject this=" << this << endl;    // previous and next node may still reference this!!!    // hope this fix is fine...    if (m_parent)    {        //have parent, take care of the tree integrity        m_parent->removeChild(this);    } //if not, it is mass a deletion, just kill everyone    RenderObject *n;    RenderObject *next;    for( n = m_first; n != 0; n = next )    {        n->setParent(0); //zero the parent        next = n->nextSibling();        delete n;    }}void RenderObject::addChild(RenderObject *newChild, RenderObject *beforeChild){    newChild->setParsing();    bool needsTable = false;    if(!newChild->isText()) {        switch(newChild->style()->display()) {        case INLINE:        case BLOCK:        case LIST_ITEM:        case RUN_IN:        case COMPACT:        case MARKER:        case TABLE:        case INLINE_TABLE:            break;        case TABLE_COLUMN_GROUP:        case TABLE_COLUMN:        case TABLE_CAPTION:        case TABLE_ROW_GROUP:        case TABLE_HEADER_GROUP:        case TABLE_FOOTER_GROUP:            //kdDebug( 6040 ) << "adding section" << endl;            if ( !isTable() )                needsTable = true;            break;        case TABLE_ROW:            //kdDebug( 6040 ) << "adding row" << endl;            if ( !isTableSection() )                needsTable = true;            break;        case TABLE_CELL:            //kdDebug( 6040 ) << "adding cell" << endl;            if ( !isTableRow() )                needsTable = true;            break;        case NONE://            kdDebug( 6000 ) << "error in RenderObject::addChild()!!!!" << endl;            break;        }    }    if ( needsTable ) {        RenderTable *table;        if( !beforeChild )            beforeChild = lastChild();        if( beforeChild && beforeChild->isAnonymousBox() && beforeChild->isTable() )            table = static_cast<RenderTable *>(beforeChild);        else {//          kdDebug( 6040 ) << "creating anonymous table" << endl;            table = new RenderTable();            RenderStyle *newStyle = new RenderStyle(m_style);            newStyle->setDisplay(TABLE);            table->setStyle(newStyle);            table->setIsAnonymousBox(true);            addChild(table, beforeChild);        }        table->addChild(newChild);        return;    }    // just add it...    newChild->setParent(this);    if (!beforeChild) {        if(m_last)        {            newChild->setPreviousSibling(m_last);            m_last->setNextSibling(newChild);            m_last = newChild;        }        else        {            m_first = m_last = newChild;        }    }    else {        if (beforeChild == m_first)            m_first = newChild;        RenderObject *newPrev = beforeChild->previousSibling();        newChild->setNextSibling(beforeChild);        beforeChild->setPreviousSibling(newChild);        if(newPrev) newPrev->setNextSibling(newChild);        newChild->setPreviousSibling(newPrev);    }    newChild->calcWidth();}void RenderObject::removeChild(RenderObject *oldChild){    //kdDebug() << "RenderObject::removeChild" << endl;    if (oldChild->previousSibling())        oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());    if (oldChild->nextSibling())        oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());    if (m_first == oldChild)        m_first = oldChild->nextSibling();    if (m_last == oldChild)        m_last = oldChild->previousSibling();    oldChild->setPreviousSibling(0);    oldChild->setNextSibling(0);    oldChild->setParent(0);    setLayouted(false);}RenderObject *RenderObject::containingBlock() const{    if(isTableCell()) {        return static_cast<const RenderTableCell *>(this)->table();    }    RenderObject *o = parent();    if(m_style->position() == FIXED) {        while ( o && !o->isRoot() )            o = o->parent();    }    else if(m_style->position() == ABSOLUTE) {        while (o && o->style()->position() == STATIC && !o->isHtml())            o = o->parent();    } else {        while(o && o->style()->display() == INLINE)            o = o->parent();    }    // this is just to make sure we return a valid element.    // the case below should never happen...    if(!o) {        if(!isRoot()) {            //assert ( false );//            kdDebug( 6040 ) << renderName() << "(RenderObject): No containingBlock!" << endl;        }        return const_cast<RenderObject *>(this);    } else        return o;}MGSize RenderObject::containingBlockSize() const{    RenderObject *o = containingBlock();    if(m_style->position() == ABSOLUTE)    {        if(o->isInline())        {            // ### fixme        }        else            return o->paddingSize();    }    return o->contentSize();}short RenderObject::containingBlockWidth() const{    // ###    return containingBlock()->contentWidth();}int RenderObject::containingBlockHeight() const{    // ###    return containingBlock()->contentHeight();}MGSize RenderObject::contentSize() const{    return MGSize(0, 0);}MGSize RenderObject::contentOffset() const{    return MGSize(0, 0);}MGSize RenderObject::paddingSize() const{    return MGSize(0, 0);}MGSize RenderObject::size() const{    return MGSize(0, 0);}void RenderObject::drawBorder(MGPainter *p, int x1, int y1, int x2, int y2, int width, BorderSide s, const MGColor &c, EBorderStyle style){    switch(style)    {    case BNONE:    case BHIDDEN:        return;    case DOTTED:        p->setPen(MGPen(c, width, MG::DotLine));        break;    case DASHED:        p->setPen(MGPen(c, width, MG::DashLine));        break;    case DOUBLE:    case GROOVE:    case RIDGE:    case INSET:    case OUTSET:        // ### don't treat them as solid    case SOLID:        p->setPen(MGPen(c, width, MG::SolidLine));        break;    }    int half = (width)/2;    switch(s)    {    case BSTop:        y1 += half; y2 += half; break;    case BSBottom:        y1 -= half; y2 -= half; break;    case BSLeft:        x1 += half; x2 += half; break;    case BSRight:        x1 -= half; x2 -= half; break;    }    p->drawLine(x1, y1, x2, y2);}void RenderObject::repaintRectangle(int x, int y, int w, int h){    if(m_parent) m_parent->repaintRectangle(x, y, w, h);}void RenderObject::repaintObject(RenderObject *o, int x, int y){    if(m_parent) m_parent->repaintObject(o, x, y);}void RenderObject::printTree(int indent) const{    QString ind;    ind.fill(' ', indent);    int childcount = 0;    for(RenderObject* c = firstChild(); c; c = c->nextSibling())        childcount++;#if 0    kdDebug(0)    << ind << renderName()                 << (childcount ?                     (QString::fromLatin1("[") + QString::number(childcount) + QString::fromLatin1("]"))                     : QString::null)                 << ": " << (void*)this                 << " il=" << (int)isInline() << " ci=" << (int) childrenInline()                 << " fl=" << (int)isFloating() << " rp=" << (int)isReplaced()                 << " an=" << (int)isAnonymousBox()                 << " ps=" << (int)isPositioned()                 << " cp=" << (int)containsPositioned()                 << " laytd=" << (int)layouted()                 << " (" << xPos() << "," << yPos() << "," << width() << "," << height() << ")" << endl;#endif    RenderObject *child = firstChild();    while( child != 0 )    {        child->printTree(indent+2);        child = child->nextSibling();    }}void RenderObject::selectionStartEnd(int& spos, int& epos){    if (parent())        parent()->selectionStartEnd(spos, epos);}void RenderObject::updateSize(){    containingBlock()->updateSize();}void RenderObject::setStyle(RenderStyle *style){    // reset style flags    m_floating = false;    m_positioned = false;    m_relPositioned = false;    m_printSpecial = false;    // ### no support for changing the display type dynamically...    //m_inline = true;    m_visible = true;    // deletion of styles is handled by the DOM elements    m_style = style;    if( m_bgImage != m_style->backgroundImage() ) {		if(m_bgImage) m_bgImage->deref();		m_bgImage = m_style->backgroundImage();		if(m_bgImage) m_bgImage->ref();    }        if( m_style->backgroundColor().isValid() || m_style->hasBorder() || m_bgImage )        m_printSpecial = true;    else	m_printSpecial = false;        if( m_style->visiblity() == HIDDEN || m_style->visiblity() == COLLAPSE )	m_visible = false;        setMinMaxKnown(false);    setLayouted(false);}void RenderObject::setContainsPositioned(bool p){    if (p)    {        m_containsPositioned = true;        if (containingBlock()!=this)            containingBlock()->setContainsPositioned(true);    }    else    {        RenderObject *n;        bool c=false;        for( n = m_first; n != 0; n = n->nextSibling() )        {            if (n->isPositioned() || n->containsPositioned())                c=true;        }        if (c)            return;        else        {            m_containsPositioned = false;            if (containingBlock()!=this)                containingBlock()->setContainsPositioned(false);        }    }}void RenderObject::setKeyboardFocus(DOM::ActivationState b){  RenderObject *actChild = firstChild();  //  printTree(0);  while(actChild) {      actChild->setKeyboardFocus(b);      actChild=actChild->nextSibling();  }  hasKeyboardFocus=b;}MGRect RenderObject::viewRect() const{    return containingBlock()->viewRect();}void RenderObject::absolutePosition(int &xPos, int &yPos, bool f){    if(m_parent)        m_parent->absolutePosition(xPos, yPos, f);    else        xPos = yPos = -1;}void RenderObject::cursorPos(int /*offset*/, int &_x, int &_y, int &height){    _x = _y = height = -1;}int RenderObject::paddingTop() const{    int cw=0;    if (style()->paddingTop().isPercent())        cw = containingBlock()->contentWidth();    return m_style->paddingTop().minWidth(cw);}int RenderObject::paddingBottom() const{    int cw=0;    if (style()->paddingBottom().isPercent())        cw = containingBlock()->contentWidth();    return m_style->paddingBottom().minWidth(cw);}int RenderObject::paddingLeft() const{    int cw=0;    if (style()->paddingLeft().isPercent())        cw = containingBlock()->contentWidth();    return m_style->paddingLeft().minWidth(cw);}int RenderObject::paddingRight() const{    int cw=0;    if (style()->paddingRight().isPercent())        cw = containingBlock()->contentWidth();    return m_style->paddingRight().minWidth(cw);}RenderObject *RenderObject::container() const{    EPosition pos = m_style->position();    RenderObject *o = 0;    if( pos == FIXED )	o = root();    else if ( pos == ABSOLUTE )	o = containingBlock();    else	o = m_parent;    return o;}RenderObject *RenderObject::root() const {    RenderObject *o = m_parent;    while( o && !o->isRoot() )	o = o->parent();    return o;}

⌨️ 快捷键说明

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