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

📄 render_box.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/** * 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) * 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. * */// -------------------------------------------------------------------------//#define DEBUG_LAYOUT#include <qpainter.h>#include "rendering/render_box.h"#include "rendering/render_replaced.h"#include "rendering/render_canvas.h"#include "rendering/render_table.h"#include "render_flexbox.h"#include "render_arena.h"#include "misc/htmlhashes.h"#include "xml/dom_nodeimpl.h"#include "xml/dom_docimpl.h"#include "render_line.h"#include <khtmlview.h>#include <kdebug.h>#include <assert.h>using namespace DOM;using namespace khtml;#define TABLECELLMARGIN -0x4000RenderBox::RenderBox(DOM::NodeImpl* node)    : RenderContainer(node){    m_minWidth = -1;    m_maxWidth = -1;    m_overrideSize = -1;    m_width = m_height = 0;    m_x = 0;    m_y = 0;    m_marginTop = 0;    m_marginBottom = 0;    m_marginLeft = 0;    m_marginRight = 0;    m_staticX = 0;    m_staticY = 0;    m_layer = 0;    m_inlineBoxWrapper = 0;}void RenderBox::setStyle(RenderStyle *_style){    RenderObject::setStyle(_style);    // The root always paints its background/border.    if (isRoot())        setShouldPaintBackgroundOrBorder(true);    setInline(_style->isDisplayInlineType());    switch(_style->position())    {    case ABSOLUTE:    case FIXED:        setPositioned(true);        break;    default:        setPositioned(false);        if (_style->isFloating())            setFloating(true);        if (_style->position() == RELATIVE)            setRelPositioned(true);    }    // FIXME: Note that we restrict overflow to blocks for now.  One day table bodies and cells     // will need to support overflow.    // We also deal with the body scroll quirk here, since it sets the scrollbars for the document.    if (_style->overflow() != OVISIBLE && isBlockFlow() && !isTableCell() &&        (!document()->isHTMLDocument() || !isBody()))        setHasOverflowClip();    if (requiresLayer()) {        if (!m_layer) {            m_layer = new (renderArena()) RenderLayer(this);            m_layer->insertOnlyThisLayer();        }    }    else if (m_layer && !isRoot() && !isCanvas()) {        m_layer->removeOnlyThisLayer();        m_layer = 0;    }    if (m_layer)        m_layer->styleChanged();        // Set the text color if we're the body.    if (isBody())        element()->getDocument()->setTextColor(_style->color());        if (style()->outlineWidth() > 0 && style()->outlineSize() > maximalOutlineSize(PaintActionOutline))        static_cast<RenderCanvas*>(document()->renderer())->setMaximalOutlineSize(style()->outlineSize());}RenderBox::~RenderBox(){    //kdDebug( 6040 ) << "Element destructor: this=" << nodeName().string() << endl;}void RenderBox::detach(){    RenderLayer* layer = m_layer;    RenderArena* arena = renderArena();        if (m_inlineBoxWrapper) {        if (!documentBeingDestroyed())            m_inlineBoxWrapper->remove();        m_inlineBoxWrapper->detach(arena);        m_inlineBoxWrapper = 0;    }    RenderContainer::detach();        if (layer)        layer->detach(arena);}int RenderBox::contentWidth() const{    int w = m_width - borderLeft() - borderRight();    w -= paddingLeft() + paddingRight();    if (includeScrollbarSize())        w -= m_layer->verticalScrollbarWidth();        //kdDebug( 6040 ) << "RenderBox::contentWidth(2) = " << w << endl;    return w;}int RenderBox::contentHeight() const{    int h = m_height - borderTop() - borderBottom();    h -= paddingTop() + paddingBottom();    if (includeScrollbarSize())        h -= m_layer->horizontalScrollbarHeight();    return h;}int RenderBox::overrideWidth() const{    return m_overrideSize == -1 ? m_width : m_overrideSize;}int RenderBox::overrideHeight() const{    return m_overrideSize == -1 ? m_height : m_overrideSize;}void RenderBox::setPos( int xPos, int yPos ){    if (xPos == m_x && yPos == m_y)        return; // Optimize for the case where we don't move at all.        m_x = xPos; m_y = yPos;}int RenderBox::width() const{    return m_width;}int RenderBox::height() const{    return m_height;}// --------------------- painting stuff -------------------------------void RenderBox::paint(PaintInfo& i, int _tx, int _ty){    _tx += m_x;    _ty += m_y;    // default implementation. Just pass paint through to the children    for (RenderObject* child = firstChild(); child; child = child->nextSibling())        child->paint(i, _tx, _ty);}void RenderBox::paintRootBoxDecorations(PaintInfo& i, int _tx, int _ty){    //kdDebug( 6040 ) << renderName() << "::paintBoxDecorations()" << _tx << "/" << _ty << endl;    QColor c = style()->backgroundColor();    CachedImage *bg = style()->backgroundImage();    bool canBeTransparent = true;    if (!c.isValid() && !bg) {        // Locate the <body> element using the DOM.  This is easier than trying        // to crawl around a render tree with potential :before/:after content and        // anonymous blocks created by inline <body> tags etc.  We can locate the <body>        // render object very easily via the DOM.        RenderObject* bodyObject = 0;        for (DOM::NodeImpl* elt = element()->firstChild(); elt; elt = elt->nextSibling()) {            if (elt->id() == ID_BODY) {                bodyObject = elt->renderer();                break;            }            else if (elt->id() == ID_FRAMESET) {                canBeTransparent = false; // Can't scroll a frameset document anyway.                break;            }        }        if (bodyObject) {            c = bodyObject->style()->backgroundColor();            bg = bodyObject->style()->backgroundImage();        }    }    // Only fill with a base color (e.g., white) if we're the root document, since iframes/frames with    // no background in the child document should show the parent's background.    if ((!c.isValid() || qAlpha(c.rgb()) == 0) && canvas()->view()) {        bool isTransparent;        DOM::NodeImpl* elt = element()->getDocument()->ownerElement();        if (elt)            isTransparent = canBeTransparent && elt->id() != ID_FRAME; // Frames are never transparent.        else            isTransparent = canvas()->view()->isTransparent();        if (isTransparent)            canvas()->view()->useSlowRepaints(); // The parent must show behind the child.        else            c = canvas()->view()->palette().active().color(QColorGroup::Base);    }        int w = width();    int h = height();    //    kdDebug(0) << "width = " << w <<endl;    int rw, rh;    if (canvas()->view()) {        rw = canvas()->view()->contentsWidth();        rh = canvas()->view()->contentsHeight();    }    else {        rw = canvas()->width();        rh = canvas()->height();    }        //    kdDebug(0) << "rw = " << rw <<endl;    int bx = _tx - marginLeft();    int by = _ty - marginTop();    int bw = kMax(w + marginLeft() + marginRight() + borderLeft() + borderRight(), rw);    int bh = kMax(h + marginTop() + marginBottom() + borderTop() + borderBottom(), rh);    // CSS2 14.2:    // " The background of the box generated by the root element covers the entire canvas."    // hence, paint the background even in the margin areas (unlike for every other element!)    // I just love these little inconsistencies .. :-( (Dirk)    int my = kMax(by, i.r.y());    paintBackground(i.p, c, bg, my, i.r.height(), bx, by, bw, bh);    if (style()->hasBorder() && style()->display() != INLINE)        paintBorder( i.p, _tx, _ty, w, h, style() );}void RenderBox::paintBoxDecorations(PaintInfo& i, int _tx, int _ty){    if (!shouldPaintWithinRoot(i))        return;    //kdDebug( 6040 ) << renderName() << "::paintDecorations()" << endl;    if (isRoot())        return paintRootBoxDecorations(i, _tx, _ty);        int w = width();    int h = height() + borderTopExtra() + borderBottomExtra();    _ty -= borderTopExtra();    int my = kMax(_ty, i.r.y());    int mh;    if (_ty < i.r.y())        mh= kMax(0, h - (i.r.y() - _ty));    else        mh = kMin(i.r.height(), h);    // The <body> only paints its background if the root element has defined a background    // independent of the body.  Go through the DOM to get to the root element's render object,    // since the root could be inline and wrapped in an anonymous block.    if (!isBody()        || element()->getDocument()->documentElement()->renderer()->style()->backgroundColor().isValid()        || element()->getDocument()->documentElement()->renderer()->style()->backgroundImage())        paintBackground(i.p, style()->backgroundColor(), style()->backgroundImage(), my, mh, _tx, _ty, w, h);       if (style()->hasBorder())        paintBorder(i.p, _tx, _ty, w, h, style());}void RenderBox::paintBackground(QPainter *p, const QColor &c, CachedImage *bg, int clipy, int cliph, int _tx, int _ty, int w, int height){    paintBackgroundExtended(p, c, bg, clipy, cliph, _tx, _ty, w, height,                            borderLeft(), borderRight());}void RenderBox::paintBackgroundExtended(QPainter *p, const QColor &c, CachedImage *bg, int clipy, int cliph,                                        int _tx, int _ty, int w, int h,                                        int bleft, int bright){    if (c.isValid() && qAlpha(c.rgb()) > 0) {        // If we have an alpha and we are painting the root element, go ahead and blend with our default        // background color (typically white).        if (qAlpha(c.rgb()) < 0xFF && isRoot() && !canvas()->view()->isTransparent())            p->fillRect(_tx, clipy, w, cliph, canvas()->view()->palette().active().color(QColorGroup::Base));        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 ) << "painting bgimage at " << _tx << "/" << _ty << endl;        // ### might need to add some correct offsets        // ### use paddingX/Y        // for propagation of <body> up to <html>        RenderStyle* sptr = style();        if ((isRoot() && element() && element()->id() == ID_HTML) && firstChild() && !style()->backgroundImage())            sptr = firstChild()->style();        int sx = 0;        int sy = 0;	    int cw,ch;        int cx,cy;        int vpab = bleft + bright;        int hpab = borderTop() + borderBottom();                // CSS2 chapter 14.2.1        if (sptr->backgroundAttachment())        {            //scroll            int pw = w - vpab;            int ph = h - 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;                int xPosition = sptr->backgroundXPosition().minWidth(pw-pixw);                if (xPosition >= 0)                    cx = _tx + xPosition;                else {                    cx = _tx;                    if (pixw == 0)                        sx = 0;                    else {                        sx = -xPosition;                        cw += xPosition;

⌨️ 快捷键说明

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