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

📄 render_table.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 1997 Martin Jones (mjones@kde.org) *           (C) 1997 Torben Weis (weis@kde.org) *           (C) 1998 Waldo Bastian (bastian@kde.org) *           (C) 1999-2003 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) *           (C) 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 TABLE_DEBUG//#define TABLE_PRINT//#define DEBUG_LAYOUT//#define BOX_DEBUG#include "rendering/render_table.h"#include "rendering/render_replaced.h"#include "rendering/render_canvas.h"#include "rendering/table_layout.h"#include "html/html_tableimpl.h"#include "misc/htmltags.h"#include "misc/htmlattrs.h"#include "rendering/render_line.h"#include "xml/dom_docimpl.h"#include <kglobal.h>#include <qapplication.h>#include <qstyle.h>#include <kdebug.h>#include <assert.h>using namespace khtml;using namespace DOM;RenderTable::RenderTable(DOM::NodeImpl* node)    : RenderBlock(node){    tCaption = 0;    head = foot = firstBody = 0;    tableLayout = 0;    m_currentBorder = 0;    rules = None;    frame = Void;    has_col_elems = false;    hspacing = vspacing = 0;    padding = 0;    needSectionRecalc = false;    padding = 0;    columnPos.resize( 2 );    columnPos.fill( 0 );    columns.resize( 1 );    columns.fill( ColumnStruct() );    columnPos[0] = 0;}RenderTable::~RenderTable(){    delete tableLayout;}void RenderTable::setStyle(RenderStyle *_style){    ETableLayout oldTableLayout = style() ? style()->tableLayout() : TAUTO;    if ( _style->display() == INLINE ) _style->setDisplay( INLINE_TABLE );    if ( _style->display() != INLINE_TABLE ) _style->setDisplay(TABLE);    RenderBlock::setStyle(_style);    // init RenderObject attributes    setInline(style()->display()==INLINE_TABLE && !isPositioned());    setReplaced(style()->display()==INLINE_TABLE);    // In the collapsed border model, there is no cell spacing.    hspacing = collapseBorders() ? 0 : style()->borderHorizontalSpacing();    vspacing = collapseBorders() ? 0 : style()->borderVerticalSpacing();    columnPos[0] = hspacing;    if ( !tableLayout || style()->tableLayout() != oldTableLayout ) {	delete tableLayout;        // According to the CSS2 spec, you only use fixed table layout if an        // explicit width is specified on the table.  Auto width implies auto table layout.	if (style()->tableLayout() == TFIXED && !style()->width().isVariable()) {	    tableLayout = new FixedTableLayout(this);#ifdef DEBUG_LAYOUT	    kdDebug( 6040 ) << "using fixed table layout" << endl;#endif	} else	    tableLayout = new AutoTableLayout(this);    }}short RenderTable::lineHeight(bool b) const{    // Inline tables are replaced elements. Otherwise, just pass off to    // the base class.    if (isReplaced())        return height()+marginTop()+marginBottom();    return RenderBlock::lineHeight(b);}short RenderTable::baselinePosition(bool b) const{    // Inline tables are replaced elements. Otherwise, just pass off to    // the base class.    if (isReplaced())        return height()+marginTop()+marginBottom();    return RenderBlock::baselinePosition(b);}void RenderTable::addChild(RenderObject *child, RenderObject *beforeChild){#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(Table)::addChild( " << child->renderName() << ", " <<                       (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;#endif    RenderObject *o = child;    if (child->element() && child->element()->id() == ID_FORM) {        RenderContainer::addChild(child,beforeChild);        return;    }    switch(child->style()->display())    {    case TABLE_CAPTION:        tCaption = static_cast<RenderBlock *>(child);        break;    case TABLE_COLUMN:    case TABLE_COLUMN_GROUP:	has_col_elems = true;        break;    case TABLE_HEADER_GROUP:	if ( !head )	    head = static_cast<RenderTableSection *>(child);	else if ( !firstBody )            firstBody = static_cast<RenderTableSection *>(child);        break;    case TABLE_FOOTER_GROUP:	if ( !foot ) {	    foot = static_cast<RenderTableSection *>(child);	    break;	}	// fall through    case TABLE_ROW_GROUP:        if(!firstBody)            firstBody = static_cast<RenderTableSection *>(child);        break;    default:        if ( !beforeChild && lastChild() &&	     lastChild()->isTableSection() && lastChild()->isAnonymous() ) {            o = lastChild();        } else {	    RenderObject *lastBox = beforeChild;	    while ( lastBox && lastBox->parent()->isAnonymous() &&		    !lastBox->isTableSection() && lastBox->style()->display() != TABLE_CAPTION )		lastBox = lastBox->parent();	    if ( lastBox && lastBox->isAnonymous() ) {		lastBox->addChild( child, beforeChild );		return;	    } else {		if ( beforeChild && !beforeChild->isTableSection() )		    beforeChild = 0;  		//kdDebug( 6040 ) << this <<" creating anonymous table section beforeChild="<< beforeChild << endl;		o = new (renderArena()) RenderTableSection(document() /* anonymous */);		RenderStyle *newStyle = new RenderStyle();		newStyle->inheritFrom(style());                newStyle->setDisplay(TABLE_ROW_GROUP);		o->setStyle(newStyle);		addChild(o, beforeChild);	    }        }        o->addChild(child);        child->setNeedsLayoutAndMinMaxRecalc();        return;    }    RenderContainer::addChild(child,beforeChild);}void RenderTable::calcWidth(){    if ( isPositioned() ) {        calcAbsoluteHorizontal();    }    RenderBlock *cb = containingBlock();    int availableWidth = cb->contentWidth();    // Subtract minimum margins    availableWidth -= style()->marginLeft().minWidth(cb->contentWidth());    availableWidth -= style()->marginRight().minWidth(cb->contentWidth());    LengthType widthType = style()->width().type();    if(widthType > Relative && style()->width().value() > 0) {	// Percent or fixed table        m_width = style()->width().minWidth( availableWidth );        if(m_minWidth > m_width) m_width = m_minWidth;    } else {        m_width = KMIN(short( availableWidth ), short(m_maxWidth));    }    // restrict width to what we really have    // EXCEPT percent tables, which are still calculated as above    availableWidth = cb->lineWidth( m_y );    if ( widthType != Percent )        m_width = KMIN( short( availableWidth ), m_width );    m_width = KMAX (m_width, m_minWidth);    // Finally, with our true width determined, compute our margins for real.    m_marginRight=0;    m_marginLeft=0;    calcHorizontalMargins(style()->marginLeft(),style()->marginRight(),availableWidth);}void RenderTable::layout(){    KHTMLAssert( needsLayout() );    KHTMLAssert( minMaxKnown() );    KHTMLAssert( !needSectionRecalc );    if (posChildNeedsLayout() && !normalChildNeedsLayout() && !selfNeedsLayout()) {        // All we have to is lay out our positioned objects.        layoutPositionedObjects(true);        setNeedsLayout(false);        return;    }    if (markedForRepaint()) {        repaintDuringLayout();        setMarkedForRepaint(false);    }    m_height = 0;    initMaxMarginValues();    //int oldWidth = m_width;    calcWidth();    m_overflowWidth = m_width;    // the optimization below doesn't work since the internal table    // layout could have changed.  we need to add a flag to the table    // layout that tells us if something has changed in the min max    // calculations to do it correctly.//     if ( oldWidth != m_width || columns.size() + 1 != columnPos.size() )    tableLayout->layout();#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(Table)::layout1() width=" << width() << ", marginLeft=" << marginLeft() << " marginRight=" << marginRight() << endl;#endif    setCellWidths();    // layout child objects    int calculatedHeight = 0;    RenderObject *child = firstChild();    while( child ) {	if ( child->needsLayout() && !(child->element() && child->element()->id() == ID_FORM) )	    child->layout();	if ( child->isTableSection() ) {	    static_cast<RenderTableSection *>(child)->calcRowHeight();	    calculatedHeight += static_cast<RenderTableSection *>(child)->layoutRows( 0 );	}	child = child->nextSibling();    }    // ### collapse caption margin    if(tCaption && tCaption->style()->captionSide() != CAPBOTTOM) {        tCaption->setPos(tCaption->marginLeft(), m_height);        m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom();    }    int bpTop = borderTop() + (collapseBorders() ? 0 : paddingTop());    int bpBottom = borderBottom() + (collapseBorders() ? 0 : paddingBottom());    m_height += bpTop;    int oldHeight = m_height;    calcHeight();    int newHeight = m_height;    m_height = oldHeight;    Length h = style()->height();    int th = -(bpTop + bpBottom); // Tables size as though CSS height includes border/padding.    if (isPositioned())        th = newHeight; // FIXME: Leave this alone for now but investigate later.    else if (h.isFixed())        th += h.value();    else if (h.isPercent())        th += calcPercentageHeight(h);    // layout rows    if ( th > calculatedHeight ) {	// we have to redistribute that height to get the constraint correctly	// just force the first body to the height needed	// ### FIXME This should take height constraints on all table sections into account and distribute	// accordingly. For now this should be good enough        if (firstBody) {            firstBody->calcRowHeight();            firstBody->layoutRows( th - calculatedHeight );        }        else if (!style()->htmlHacks()) {            // Completely empty tables (with no sections or anything) should at least honor specified height            // in strict mode.            m_height += th;        }    }    int bl = borderLeft();    if (!collapseBorders())        bl += paddingLeft();    // position the table sections    if ( head ) {	head->setPos(bl, m_height);	m_height += head->height();    }    RenderObject *body = firstBody;    while ( body ) {	if ( body != head && body != foot && body->isTableSection() ) {	    body->setPos(bl, m_height);	    m_height += body->height();	}	body = body->nextSibling();    }    if ( foot ) {	foot->setPos(bl, m_height);	m_height += foot->height();    }    m_height += bpBottom;    if(tCaption && tCaption->style()->captionSide()==CAPBOTTOM) {        tCaption->setPos(tCaption->marginLeft(), m_height);        m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom();    }    if (canvas()->pagedMode()) {        RenderObject *child = firstChild();        // relayout taking real position into account        while( child ) {            if ( !(child->element() && child->element()->id() == ID_FORM) ) {                child->setNeedsLayout(true);                child->layout();                if (child->containsPageBreak()) setContainsPageBreak(true);                if (child->needsPageClear()) setNeedsPageClear(true);            }            child = child->nextSibling();        }    }    //kdDebug(0) << "table height: " << m_height << endl;    // table can be containing block of positioned elements.    // ### only pass true if width or height changed.    layoutPositionedObjects( true );    m_overflowHeight = m_height;    setNeedsLayout(false);}void RenderTable::setCellWidths(){#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(Table, this=0x" << this << ")::setCellWidths()" << endl;#endif    RenderObject *child = firstChild();    while( child ) {	if ( child->isTableSection() )	    static_cast<RenderTableSection *>(child)->setCellWidths();	child = child->nextSibling();    }}void RenderTable::paint( PaintInfo& pI, int _tx, int _ty){    if(needsLayout()) return;    _tx += xPos();    _ty += yPos();#ifdef TABLE_PRINT    kdDebug( 6040 ) << "RenderTable::paint() w/h = (" << width() << "/" << height() << ")" << endl;#endif    if (!overhangingContents() && !isRelPositioned() && !isPositioned())    {        int os = 2*maximalOutlineSize(pI.phase);        if((_ty > pI.r.y() + pI.r.height() + os) || (_ty + height() < pI.r.y() - os)) return;        if((_tx > pI.r.x() + pI.r.width() + os) || (_tx + width() < pI.r.x() - os)) return;    }#ifdef TABLE_PRINT    kdDebug( 6040 ) << "RenderTable::paint(2) " << _tx << "/" << _ty << " (" << _y << "/" << _h << ")" << endl;#endif    if (pI.phase == PaintActionOutline)        paintOutline(pI.p, _tx, _ty, width(), height(), style());    if(( pI.phase == PaintActionElementBackground || pI.phase == PaintActionChildBackground )

⌨️ 快捷键说明

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