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

📄 render_box.cpp

📁 monqueror一个很具有参考价值的源玛
💻 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.2 2002/01/28 04:31:02 leon Exp $ */// -------------------------------------------------------------------------//#define DEBUG_LAYOUT#include <assert.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 "dom_string.h"#include "dom_node.h"#include "dom_textimpl.h"#include "dom_stringimpl.h"#include "dom_exception.h"#include "htmlhashes.h"#include "mghtmlview.h"#include "render_box.h"#include "render_style.h"#include "render_object.h"#include "render_text.h"#include "render_root.h"#include "render_replaced.h"#include "kdebug.h"using namespace DOM;using namespace khtml;RenderBox::RenderBox()    : RenderObject(){    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);    switch(style->position())    {    case ABSOLUTE:    case FIXED:        m_positioned = true;        break;    default:        if(style->isFloating()) {            m_floating = true;        } else {            if(style->position() == RELATIVE)			{//				kdDebug(0) << "set rel pos true" << endl;                m_relPositioned = true;			}        }    }}RenderBox::~RenderBox(){    //kdDebug( 6040 ) << "Element destructor: this=" << nodeName().string() << endl;}MGSize RenderBox::contentSize() const{    int w = m_width;    int h = m_height;    if(m_style->hasBorder())    {        w -= borderLeft() + borderRight();        h -= borderTop() + borderBottom();    }    if(m_style->hasPadding())    {        w -= paddingLeft() + paddingRight();        h -= paddingTop() + paddingBottom();    }    return MGSize(w, h);}short RenderBox::contentWidth() const{    short w = m_width;//fprintf(stderr,"render_box w:%d\n",w);//kdDebug( 6040 ) << "RenderBox::contentWidth(1) = " << m_width << endl;    if(m_style->hasBorder())        w -= borderLeft() + borderRight();    if(m_style->hasPadding())        w -= paddingLeft() + paddingRight();    //kdDebug( 6040 ) << "RenderBox::contentWidth(2) = " << w << endl;//fprintf(stderr,"---quit render_box w:%d\n",w);	return w;}int RenderBox::contentHeight() const{    int h = m_height;    if(m_style->hasBorder())        h -= borderTop() + borderBottom();    if(m_style->hasPadding())        h -= paddingTop() + paddingBottom();    return h;}MGSize RenderBox::contentOffset() const{    // ###    //int xOff = 0;    //int yOff = 0;    return MGSize(0, 0);}MGSize RenderBox::paddingSize() const{    return MGSize(0, 0);}MGSize RenderBox::size() const{    return MGSize(0, 0);}short RenderBox::width() const{    return m_width;}int RenderBox::height() const{    return m_height;}// --------------------- printing stuff -------------------------------void RenderBox::print(MGPainter *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 MGPixmap &, const MGRect&, MGCachedImage *image, bool *){    if(image && image->pixmap_size() == image->valid_rect().size())        repaint();      //repaint bg when it finished loading}void RenderBox::printBoxDecorations(MGPainter *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);    printBackground(p, m_style->backgroundColor(), m_bgImage, my, mh, _tx, _ty, w, h);    if(m_style->hasBorder())        printBorder(p, _tx, _ty, w, h);}void RenderBox::printBackground (MGPainter *p, const MGColor &c, const MGCachedImage *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()) {        //kdDebug( 6040 ) << "printing bgimage at " << _tx << "/" << _ty << endl;        // ### might need to add some correct offsets        // ### use paddingX/Y        int sx = 0;        int sy = 0;        //hacky stuff        EBackgroundRepeat bgr = m_style->backgroundRepeat();	bool scroll = m_style->backgroundAttachment();        if ( isHtml() && firstChild() && !m_bgImage ) {            bgr = firstChild()->style()->backgroundRepeat();            scroll = firstChild()->style()->backgroundAttachment();	}	int cx = _tx;	int cy = clipy;	int cw = w;	int ch = cliph;        switch(bgr) {        case NO_REPEAT:            cw = QMIN(bg->pixmap_size().width(), w);	    cx = _tx + style()->backgroundXPosition().minWidth((w - cw)/2);            /* nobreak */        case REPEAT_X:            ch = QMIN(bg->pixmap_size().height(), h);	    cy = _ty + style()->backgroundYPosition().minWidth((h -ch)/2);            break;        case REPEAT_Y:            cw = QMIN(bg->pixmap_size().width(), w);	    cx = _tx + style()->backgroundXPosition().minWidth((w - cw)/2);        case REPEAT:            // make sure that the pixmap is tiled correctly            // because we clip the tiling to the visible area (for speed reasons)            if(bg->pixmap_size().height() && scroll)                sy = (clipy - _ty) % bg->pixmap_size().height();            break;        }        if( !scroll ) {            MGRect r = viewRect();            //kdDebug(0) << "fixed background r.y=" << r.y() << endl;	    if( isHtml() ) {		cy += r.y();		cx += r.x();	    }            sx = cx - r.x();            sy = cy - r.y();        }	p->drawTiledPixmap(cx, cy, cw, ch, bg->tiled_pixmap(c), sx, sy);    }}void RenderBox::printBorder(MGPainter *p, int _tx, int _ty, int w, int h){    int bottom = _ty + h;    int right = _tx + w;    right -= (m_style->borderRightWidth() & 1);    bottom -= (m_style->borderBottomWidth() & 1);    MGColor c;    if(m_style->borderTopStyle() != BNONE) {        c = m_style->borderTopColor();        if(!c.isValid()) c = m_style->color();        drawBorder(p, _tx, _ty, right, _ty, m_style->borderTopWidth(),                   BSTop, c, m_style->borderTopStyle());    }    if(m_style->borderBottomStyle() != BNONE) {        c = m_style->borderBottomColor();        if(!c.isValid()) c = m_style->color();        drawBorder(p, _tx, bottom, right, bottom, m_style->borderBottomWidth(),                   BSBottom, c, m_style->borderBottomStyle());    }    if(m_style->borderLeftStyle() != BNONE) {        c = m_style->borderLeftColor();        if(!c.isValid()) c = m_style->color();        drawBorder(p, _tx, _ty, _tx, bottom, m_style->borderLeftWidth(),                   BSLeft, c, m_style->borderLeftStyle());    }    if(m_style->borderRightStyle() != BNONE) {        c = m_style->borderRightColor();        if(!c.isValid()) c = m_style->color();        drawBorder(p, right, _ty, right, bottom, m_style->borderRightWidth(),                   BSRight, c, m_style->borderRightStyle());    }}void RenderBox::outlineBox(MGPainter *p, int _tx, int _ty, const char *color){    p->setPen(MGPen(MGColor(color), 1, MG::DotLine));    p->setBrush( MG::NoBrush );    p->drawRect(_tx, _ty, m_width, m_height);}void RenderBox::close(){    setParsing(false);    calcWidth();    calcHeight();    calcMinMaxWidth();    if(containingBlockWidth() < m_minWidth && m_parent)        containingBlock()->updateSize();    else if(!isInline() || isReplaced())    {        layout();    }}short RenderBox::containingBlockWidth() const{    if (style()->htmlHacks() && style()->flowAroundFloats() && containingBlock()->isFlow()            && style()->width().isVariable())        return static_cast<RenderFlow*>(containingBlock())->lineWidth(m_y);    else        return containingBlock()->contentWidth();}void RenderBox::absolutePosition(int &xPos, int &yPos, bool f){    if ( m_style->position() == FIXED )	f = true;    RenderObject *o = container();    if( o ) {        o->absolutePosition(xPos, yPos, f);        if((!isInline() || isReplaced()) && xPos != -1)            xPos += m_x, yPos += m_y;    }    else        xPos = yPos = -1;}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    if (parsing())    {        setLayouted(false);        containingBlock()->updateHeight();        return;    }    if(!isInline() || isReplaced())    {        int oldHeight = m_height;        setLayouted(false);        if (hasOverhangingFloats()) {            if(containingBlock() != this) containingBlock()->updateHeight();        }        layout();        if(m_height != oldHeight) {            if(containingBlock() != this) containingBlock()->updateHeight();        } else {            containingBlock()->repaint();        }    }}void RenderBox::position(int x, int y, int, int, int, bool){    m_x = x + marginLeft();    m_y = y;    // ### paddings    //m_width = width;		/*	if( isWidget() )	{		int _x = m_x+borderLeft()+paddingLeft();		int _y = m_y+borderTop()+paddingTop();		//static_cast<RenderWidget*>(this)->m_widget->moveWindow( _x, _y );	}	*/}short RenderBox::verticalPositionHint() const{    switch(m_style->verticalAlign())    {    case BASELINE:        //kdDebug( 6040 ) << "aligned to baseline" << endl;        return contentHeight();    case SUB:        // ###    case SUPER:        // ###    case TOP:        return PositionTop;    case TEXT_TOP:#if 1        return MGFontMetrics(m_style->font(), m_part).ascent();#else        return MGFontMetrics(m_style->font(), m_part).descent();#endif    case MIDDLE:        return contentHeight()/2;    case BOTTOM:        return PositionBottom;    case TEXT_BOTTOM:#if 1        return MGFontMetrics(m_style->font(), m_part).descent();#else        return MGFontMetrics(m_style->font(), m_part).ascent();#endif    }    return 0;}short RenderBox::baselineOffset() const{

⌨️ 快捷键说明

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