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

📄 render_box.cpp

📁 将konqueror浏览器移植到ARM9 2410中
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/** * 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_box.cpp,v 1.138 2001/07/29 19:48:46 koivisto Exp $ */// -------------------------------------------------------------------------//#define DEBUG_LAYOUT#include "dom_string.h"#include <qpainter.h>#include <qfontmetrics.h>#include <qstack.h>#include "dom_node.h"#include "dom_textimpl.h"#include "dom_stringimpl.h"#include "dom_exception.h"#include "misc/helper.h"#include "htmlhashes.h"#include "khtmlview.h"#include "render_box.h"#include "render_style.h"#include "render_object.h"#include "render_text.h"#include "render_replaced.h"#include "render_root.h"#include <kdebug.h>#include <assert.h>#include "misc/loader.h"using namespace DOM;using namespace khtml;#define TABLECELLMARGIN -0x4000RenderBox::RenderBox()    : RenderContainer(){    m_minWidth = -1;    m_maxWidth = -1;    m_width = m_height = 0;    m_x = 0;    m_y = 0;    m_marginTop = 0;    m_marginBottom = 0;    m_marginLeft = 0;    m_marginRight = 0;}void RenderBox::setStyle(RenderStyle *_style){    RenderObject::setStyle(_style);    // ### move this into the parser. --> should work. Lars    // if only horizontal position was defined, vertical should be 50%    //if(!_style->backgroundXPosition().isVariable() && _style->backgroundYPosition().isVariable())    //style()->setBackgroundYPosition(Length(50, Percent));    switch(_style->position())    {    case ABSOLUTE:    case FIXED:        setPositioned(true);        break;    default:        setPositioned(false);        if(_style->isFloating()) {            setFloating(true);        } else {            if(_style->position() == RELATIVE)                setRelPositioned(true);        }    }}RenderBox::~RenderBox(){    //kdDebug( 6040 ) << "Element destructor: this=" << nodeName().string() << endl;}short RenderBox::contentWidth() const{    short w = m_width - style()->borderLeftWidth() - style()->borderRightWidth();    if(style()->hasPadding())        w -= paddingLeft() + paddingRight();    //kdDebug( 6040 ) << "RenderBox::contentWidth(2) = " << w << endl;    return w;}int RenderBox::contentHeight() const{    int h = m_height - style()->borderTopWidth() - style()->borderBottomWidth();    if(style()->hasPadding())        h -= paddingTop() + paddingBottom();    return h;}void RenderBox::setPos( int xPos, int yPos ){    m_x = xPos; m_y = yPos;#if 1    if(m_x != xPos || m_y != yPos)    {        bool cw = containsWidget();        if ( !cw && parent() && parent()->containsWidget() )            cw = true;        if ( cw ) {            int x,y;            absolutePosition(x,y);            // propagate position change to childs            for(RenderObject *child = firstChild(); child; child = child->nextSibling()) {                if(child->isWidget())                    static_cast<RenderWidget*>(child)->placeWidget(x+child->xPos(),y+child->yPos());            }        }    }#endif}short RenderBox::width() const{    return m_width;}int RenderBox::height() const{    return m_height;}// --------------------- printing stuff -------------------------------void RenderBox::print(QPainter *p, int _x, int _y, int _w, int _h,                                  int _tx, int _ty){    _tx += m_x;    _ty += m_y;    // default implementation. Just pass things through to the children    RenderObject *child = firstChild();    while(child != 0)    {        child->print(p, _x, _y, _w, _h, _tx, _ty);        child = child->nextSibling();    }}void RenderBox::setPixmap(const QPixmap &, const QRect&, CachedImage *image, bool *){    if(image && image->pixmap_size() == image->valid_rect().size() && parent())        repaint();      //repaint bg when it finished loading}void RenderBox::printBoxDecorations(QPainter *p,int, int _y,                                       int, int _h, int _tx, int _ty){    //kdDebug( 6040 ) << renderName() << "::printDecorations()" << endl;    int w = width();    int h = height() + borderTopExtra() + borderBottomExtra();    _ty -= borderTopExtra();    int my = QMAX(_ty,_y);    int mh;    if (_ty<_y)        mh= QMAX(0,h-(_y-_ty));    else        mh = QMIN(_h,h);    if ( !root()->printingMode() )        printBackground(p, style()->backgroundColor(), style()->backgroundImage(), my, mh, _tx, _ty, w, h);    if(style()->hasBorder())        printBorder(p, _tx, _ty, w, h, style());}void RenderBox::printBackground(QPainter *p, const QColor &c, CachedImage *bg, int clipy, int cliph, int _tx, int _ty, int w, int h){    if(c.isValid())        p->fillRect(_tx, clipy, w, cliph, c);    // no progressive loading of the background image    if(bg && bg->pixmap_size() == bg->valid_rect().size() && !bg->isTransparent() && !bg->isErrorImage()) {        //kdDebug( 6040 ) << "printing bgimage at " << _tx << "/" << _ty << endl;        // ### might need to add some correct offsets        // ### use paddingX/Y        //hacky stuff        RenderStyle* sptr = style();        if ( isHtml() && firstChild() && !style()->backgroundImage() )            sptr = firstChild()->style();        int sx = 0;        int sy = 0;        	    int cw,ch;        int cx,cy;        int vpab = borderRight() + borderLeft();        int hpab = borderTop() + borderBottom();        // CSS2 chapter 14.2.1                if (sptr->backgroundAttachment())        {            //scroll            int pw = m_width - vpab;            int ph = m_height - hpab;            int pixw = bg->pixmap_size().width();            int pixh = bg->pixmap_size().height();            EBackgroundRepeat bgr = sptr->backgroundRepeat();            if( (bgr == NO_REPEAT || bgr == REPEAT_Y) && w > pixw ) {                cw = pixw;                cx = _tx + sptr->backgroundXPosition().minWidth(pw-pixw);            } else {                cw = w-vpab;                cx = _tx;                sx =  pixw - ((sptr->backgroundXPosition().minWidth(pw-pixw)) % pixw );            }                        cx += borderLeft();            if( (bgr == NO_REPEAT || bgr == REPEAT_X) && h > pixh ) {                ch = pixh;                cy = _ty + sptr->backgroundYPosition().minWidth(ph-pixh);            } else {                ch = h-hpab;                cy = _ty;                sy = pixh - ((sptr->backgroundYPosition().minWidth(ph-pixh)) % pixh );            }                                    cy += borderTop();        }         else        {            //fixed            QRect vr = viewRect();            int pw = vr.width();               int ph = vr.height();                        int pixw = bg->pixmap_size().width();            int pixh = bg->pixmap_size().height();            EBackgroundRepeat bgr = sptr->backgroundRepeat();            if( (bgr == NO_REPEAT || bgr == REPEAT_Y) && w > pixw ) {                cw = pixw;                cx = vr.x() + sptr->backgroundXPosition().minWidth(pw-pixw);            } else {                cw = pw;                cx = vr.x();                sx =  pixw - ((sptr->backgroundXPosition().minWidth(pw-pixw)) % pixw );            }            if( (bgr == NO_REPEAT || bgr == REPEAT_X) && h > pixh ) {                ch = pixh;                cy = vr.y() + sptr->backgroundYPosition().minWidth(ph-pixh);            } else {                ch = ph;                cy = vr.y();                sy = pixh - ((sptr->backgroundYPosition().minWidth(ph-pixh)) % pixh );            }                          QRect fix(cx,cy,cw,ch);            QRect ele(_tx+borderLeft()+paddingLeft(),_ty+borderTop()+paddingTop(),w-vpab,h-hpab);            QRect b = fix.intersect(ele);            sx+=b.x()-cx;            sy+=b.y()-cy;            cx=b.x();cy=b.y();cw=b.width();ch=b.height();                }//        kdDebug() << "cx="<<cx << " cy="<<cy<< " cw="<<cw << " ch="<<ch << " sx="<<sx << " sy="<<sy << endl;                if (cw>0 && ch>0)            p->drawTiledPixmap(cx, cy, cw, ch, bg->tiled_pixmap(c), sx, sy);    }}void RenderBox::outlineBox(QPainter *p, int _tx, int _ty, const char *color){    p->setPen(QPen(QColor(color), 1, Qt::DotLine));    p->setBrush( Qt::NoBrush );    p->drawRect(_tx, _ty, m_width, m_height);}void RenderBox::calcClip(QPainter* p, int tx, int ty, const QRegion& old){        int bl=borderLeft(),bt=borderTop(),bb=borderBottom(),br=borderRight();    int clipx = tx+bl;    int clipy = ty+bt;    int clipw = m_width-bl-br;    int cliph = m_height-bt-bb;    if (!style()->clipLeft().isVariable())    {        int c=style()->clipLeft().width(m_width-bl-br);        clipx+=c;        clipw-=c;      }    if (!style()->clipRight().isVariable())    {        clipw-=style()->clipRight().width(m_width-bl-br);    }    if (!style()->clipTop().isVariable())    {        int c=style()->clipTop().width(m_height-bt-bb);        clipy+=c;        cliph-=c;                  }     if (!style()->clipBottom().isVariable())    {        cliph-=style()->clipBottom().width(m_height-bt-bb);    }//    kdDebug( 6040 ) << "setting clip("<<clipx<<","<<clipy<<","<<clipw<<","<<cliph<<")"<<endl;                QRect cr(clipx,clipy,clipw,cliph);    cr = p->xForm(cr);    QRegion creg(cr);    if (!old.isNull())        creg = old.intersect(creg);    p->setClipRegion(creg);    }void RenderBox::close(){    setParsing(false);    calcWidth();    calcHeight();    calcMinMaxWidth();    if(containingBlockWidth() < m_minWidth && parent())        containingBlock()->updateSize();    else if(!isInline() || isReplaced())    {        layout();    }}short RenderBox::containingBlockWidth() const{    if ( ( style()->htmlHacks() || isTable() ) && style()->flowAroundFloats() && containingBlock()->isFlow()            && style()->width().isVariable())        return static_cast<RenderFlow*>(containingBlock())->lineWidth(m_y);    else        return containingBlock()->contentWidth();}bool RenderBox::absolutePosition(int &xPos, int &yPos, bool f){    if ( style()->position() == FIXED )	f = true;    RenderObject *o = container();    if( o && o->absolutePosition(xPos, yPos, f))    {        if(!isInline() || isReplaced())            xPos += m_x, yPos += m_y;        if(isRelPositioned())            relativePositionOffset(xPos, yPos);        return true;    }    else    {        xPos = yPos = 0;        return false;    }}void RenderBox::updateSize(){#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(RenderBox) " << this << " ::updateSize()" << endl;#endif    int oldMin = m_minWidth;    int oldMax = m_maxWidth;    setMinMaxKnown(false);    calcMinMaxWidth();    if ((isInline() || isFloating() || containsSpecial()) && parent())    {        if (!isInline())            setLayouted(false);        parent()->updateSize();        return;    }    if(m_minWidth > containingBlockWidth() || m_minWidth != oldMin ||        m_maxWidth != oldMax || isReplaced())    {        setLayouted(false);        if(containingBlock() != this) containingBlock()->updateSize();    }    else        updateHeight();}void RenderBox::updateHeight(){#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(RenderBox) " << this << " ::updateHeight()" << endl;#endif    RenderObject* cb = containingBlock();    if (parsing())    {        if (layouted())        {            setLayouted(false);            if(cb != this) cb->updateHeight();        } else {            RenderRoot *rt = root();            if( rt )              rt->updateHeight();	}        return;    }    if(!isInline() || isReplaced())    {        int oldHeight = m_height;        setLayouted(false);	bool overhanging = hasOverhangingFloats();        layout();	overhanging |= hasOverhangingFloats();	if ( overhanging ) {	    if ( nextSibling() )		nextSibling()->setLayouted( false );	    if(cb != this) cb->updateHeight();	} else if(m_height != oldHeight) {	    if(cb != this) cb->updateHeight();	} else {	    cb->repaint();	}    }}void RenderBox::position(int x, int y, int, int, int, bool, bool){    m_x = x + marginLeft();    m_y = y;    // ### paddings    //m_width = width;}void RenderBox::repaint(){    //kdDebug( 6040 ) << "repaint!" << endl;    int ow = style() ? style()->outlineWidth() : 0;    repaintRectangle(-ow, -ow, m_width+ow*2, m_height+ow*2);}void RenderBox::repaintRectangle(int x, int y, int w, int h, bool f){    x += m_x;    y += m_y;        if (style()->position()==FIXED) f=true;                // kdDebug( 6040 ) << "RenderBox(" << renderName() << ")::repaintRectangle (" << x << "/" << y << ") (" << w << "/" << h << ")" << endl;    RenderObject *o = container();    if( o ) o->repaintRectangle(x, y, w, h, f);}void RenderBox::relativePositionOffset(int &tx, int &ty){    if(!style()->left().isVariable())        tx += style()->left().width(containingBlockWidth());    else if(!style()->right().isVariable())        tx -= style()->right().width(containingBlockWidth());    if(!style()->top().isVariable())    {        if (!style()->top().isPercent()                || containingBlock()->style()->height().isFixed())            ty += style()->top().width(containingBlockHeight());    }    else if(!style()->bottom().isVariable())    {        if (!style()->bottom().isPercent()                || containingBlock()->style()->height().isFixed())            ty -= style()->bottom().width(containingBlockHeight());    }}

⌨️ 快捷键说明

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