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

📄 render_box.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) *           (C) 2002-2003 Apple Computer, Inc. *           (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */// -------------------------------------------------------------------------//#define DEBUG_LAYOUT//#define CLIP_DEBUG#include <qpainter.h>#include "misc/loader.h"#include "rendering/render_replaced.h"#include "rendering/render_canvas.h"#include "rendering/render_table.h"#include "rendering/render_inline.h"#include "rendering/render_block.h"#include "rendering/render_line.h"#include "rendering/render_layer.h"#include "misc/htmlhashes.h"#include "xml/dom_nodeimpl.h"#include "xml/dom_docimpl.h"#include "html/html_elementimpl.h"#include <khtmlview.h>#include <kdebug.h>#include <kglobal.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_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_placeHolderBox = 0;    m_layer = 0;}RenderBlock* RenderBox::createAnonymousBlock(){    RenderStyle *newStyle = new RenderStyle();    newStyle->inheritFrom(style());    newStyle->setDisplay(BLOCK);    RenderBlock *newBox = new (renderArena()) RenderBlock(document() /* anonymous*/);    newBox->setStyle(newStyle);    return newBox;}void RenderBox::restructureParentFlow() {    if (!parent() || parent()->childrenInline() == isInline())        return;    // We have gone from not affecting the inline status of the parent flow to suddenly    // having an impact.  See if there is a mismatch between the parent flow's    // childrenInline() state and our state.    if (!isInline()) {        if (parent()->isRenderInline()) {            // We have to split the parent flow.            RenderInline* parentInline = static_cast<RenderInline*>(parent());            RenderBlock* newBox = parentInline->createAnonymousBlock();            RenderFlow* oldContinuation = parent()->continuation();            parentInline->setContinuation(newBox);            RenderObject* beforeChild = nextSibling();            parent()->removeChildNode(this);            parentInline->splitFlow(beforeChild, newBox, this, oldContinuation);        }        else if (parent()->isRenderBlock())            static_cast<RenderBlock*>(parent())->makeChildrenNonInline();    }    else {        // An anonymous block must be made to wrap this inline.        RenderBlock* box = createAnonymousBlock();        parent()->insertChildNode(box, this);        box->appendChildNode(parent()->removeChildNode(this));    }}void RenderBox::setStyle(RenderStyle *_style){    bool affectsParent = style() && isFloatingOrPositioned() &&         (!_style->isFloating() && _style->position() != ABSOLUTE && _style->position() != FIXED) &&         parent() && (parent()->isBlockFlow() || parent()->isInlineFlow());    RenderContainer::setStyle(_style);    // The root always paints its background/border.    if (isRoot())        setShouldPaintBackgroundOrBorder(true);    switch(_style->display())    {    case INLINE:    case INLINE_BLOCK:    case INLINE_TABLE:        setInline(true);        break;    case RUN_IN:        if (isInline() && parent() && parent()->childrenInline())            break;    default:        setInline(false);    }    switch(_style->position())    {    case ABSOLUTE:    case FIXED:        setPositioned(true);        break;    default:        setPositioned(false);        if( !isTableCell() && _style->isFloating() )            setFloating(true);        if( _style->position() == RELATIVE )            setRelPositioned(true);    }    if (requiresLayer()) {        if (!m_layer) {            m_layer = new (renderArena()) RenderLayer(this);            m_layer->insertOnlyThisLayer();        }    }    else if (m_layer && !isCanvas()) {        m_layer->removeOnlyThisLayer();        m_layer = 0;    }    if (m_layer) {        // Make sure our z-index values are only applied if we're positioned or        // relpositioned.        if (!isPositioned() && !isRelPositioned()) {            // Set the auto z-index flag.            if (isRoot())                style()->setZIndex(0);            else                style()->setHasAutoZIndex();        }        m_layer->styleChanged();    }    // ### outlineSize() and outlineOffset() not merged yet    if (style()->outlineWidth() > 0 && style()->outlineWidth() > maximalOutlineSize(PaintActionOutline))        static_cast<RenderCanvas*>(document()->renderer())->setMaximalOutlineSize(style()->outlineWidth());    if (affectsParent)        restructureParentFlow();}RenderBox::~RenderBox(){    //kdDebug( 6040 ) << "Element destructor: this=" << nodeName().string() << endl;}void RenderBox::detach(){    RenderLayer* layer = m_layer;    RenderArena* arena = renderArena();    RenderContainer::detach();    if (layer)        layer->detach(arena);}InlineBox* RenderBox::createInlineBox(bool /*makePlaceHolderBox*/, bool /*isRootLineBox*/){    if (m_placeHolderBox)        m_placeHolderBox->detach(renderArena());    return (m_placeHolderBox = new (renderArena()) InlineBox(this));}void RenderBox::deleteInlineBoxes(RenderArena* arena){    if (m_placeHolderBox) {        m_placeHolderBox->detach( arena ? arena : renderArena() );        m_placeHolderBox = 0;    }}short RenderBox::contentWidth() const{    short w = m_width - style()->borderLeftWidth() - style()->borderRightWidth();    w -= paddingLeft() + paddingRight();    if (m_layer && style()->scrollsOverflow())        w -= m_layer->verticalScrollbarWidth();    //kdDebug( 6040 ) << "RenderBox::contentWidth(2) = " << w << endl;    return w;}int RenderBox::contentHeight() const{    int h = m_height - style()->borderTopWidth() - style()->borderBottomWidth();    h -= paddingTop() + paddingBottom();    if (m_layer && style()->scrollsOverflow())        h -= m_layer->horizontalScrollbarHeight();    return h;}void RenderBox::setPos( int xPos, int yPos ){    m_x = xPos; m_y = yPos;}short RenderBox::width() const{    return m_width;}int RenderBox::height() const{    return m_height;}void RenderBox::setWidth( int width ){    m_width = width;}void RenderBox::setHeight( int height ){    m_height = height;}int RenderBox::calcBoxHeight(int h) const{    if (style()->boxSizing() == CONTENT_BOX)        h += borderTop() + borderBottom() + paddingTop() + paddingBottom();    return h;}int RenderBox::calcBoxWidth(int w) const{    if (style()->boxSizing() == CONTENT_BOX)        w += borderLeft() + borderRight() + paddingLeft() + paddingRight();    return w;}int RenderBox::calcContentHeight(int h) const{    if (style()->boxSizing() == BORDER_BOX)        h -= borderTop() + borderBottom() + paddingTop() + paddingBottom();    return kMax(0, h);}int RenderBox::calcContentWidth(int w) const{    if (style()->boxSizing() == BORDER_BOX)        w -= borderLeft() + borderRight() + paddingLeft() + paddingRight();    return kMax(0, w);}// --------------------- painting stuff -------------------------------void RenderBox::paint(PaintInfo& i, int _tx, int _ty){    _tx += m_x;    _ty += m_y;    if (style()->hidesOverflow() && m_layer)        m_layer->subtractScrollOffset(_tx, _ty);    // default implementation. Just pass things through to the children    for(RenderObject* child = firstChild(); child; child = child->nextSibling())        child->paint(i, _tx, _ty);}void RenderBox::paintRootBoxDecorations(PaintInfo& paintInfo, int _tx, int _ty){    //kdDebug( 6040 ) << renderName() << "::paintRootBoxDecorations()" << _tx << "/" << _ty << endl;    const BackgroundLayer* bgLayer = style()->backgroundLayers();    QColor bgColor = style()->backgroundColor();    if (document()->isHTMLDocument() && !style()->hasBackground()) {        // 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.        HTMLElementImpl* body = document()->body();        RenderObject* bodyObject = (body && body->id() == ID_BODY) ? body->renderer() : 0;        if (bodyObject) {            bgLayer = bodyObject->style()->backgroundLayers();            bgColor = bodyObject->style()->backgroundColor();        }    }    if( !bgColor.isValid() && canvas()->view())        bgColor = 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()->docWidth();        rh = canvas()->docHeight();    }    //    kdDebug(0) << "rw = " << rw <<endl;    int bx = _tx - marginLeft();    int by = _ty - marginTop();    int bw = QMAX(w + marginLeft() + marginRight() + borderLeft() + borderRight(), rw);    int bh = QMAX(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, paintInfo.r.y());    paintBackgrounds(paintInfo.p, bgColor, bgLayer, my, paintInfo.r.height(), bx, by, bw, bh);    if(style()->hasBorder())        paintBorder( paintInfo.p, _tx, _ty, w, h, style() );}void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, int _tx, int _ty){    //kdDebug( 6040 ) << renderName() << "::paintDecorations()" << endl;    if(isRoot())        return paintRootBoxDecorations(paintInfo, _tx, _ty);    int w = width();    int h = height() + borderTopExtra() + borderBottomExtra();    _ty -= borderTopExtra();    int my = kMax(_ty,paintInfo.r.y());    int end = kMin( paintInfo.r.y() + paintInfo.r.height(), _ty + h );    int mh = end - my;   // 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() || !document()->isHTMLDocument() || document()->documentElement()->renderer()->style()->hasBackground())        paintBackgrounds(paintInfo.p, style()->backgroundColor(), style()->backgroundLayers(), my, mh, _tx, _ty, w, h);   if(style()->hasBorder()) {        paintBorder(paintInfo.p, _tx, _ty, w, h, style());    }}void RenderBox::paintBackgrounds(QPainter *p, const QColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph, int _tx, int _ty, int w, int height) {    if (!bgLayer) return;    paintBackgrounds(p, c, bgLayer->next(), clipy, cliph, _tx, _ty, w, height);    paintBackground(p, c, bgLayer, clipy, cliph, _tx, _ty, w, height);}void RenderBox::paintBackground(QPainter *p, const QColor& c, const BackgroundLayer* bgLayer, int clipy, int cliph, int _tx, int _ty, int w, int height){    paintBackgroundExtended(p, c, bgLayer, clipy, cliph, _tx, _ty, w, height,                            borderLeft(), borderRight());}void RenderBox::paintBackgroundExtended(QPainter *p, const QColor &c, const BackgroundLayer* bgLayer, int clipy, int cliph,                                        int _tx, int _ty, int w, int h,                                        int bleft, int bright){    if ( cliph < 0 )	return;    CachedImage* bg = bgLayer->backgroundImage();    bool shouldPaintBackgroundImage = bg && bg->pixmap_size() == bg->valid_rect().size() && !bg->isTransparent() && !bg->isErrorImage();    QColor bgColor = c;    // Paint the color first underneath all images.    if (!bgLayer->next() && bgColor.isValid() && qAlpha(bgColor.rgb()) > 0)        p->fillRect(_tx, clipy, w, cliph, bgColor);    // no progressive loading of the background image    if (shouldPaintBackgroundImage) {        int sx = 0;        int sy = 0;        int cw,ch;        int cx,cy;        int vpab = bleft + bright;        int hpab = borderTop() + borderBottom();

⌨️ 快捷键说明

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