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

📄 render_table.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#ifndef NDEBUGvoid RenderTable::dump(QTextStream *stream, QString ind) const{    if (tCaption)	*stream << " tCaption";    if (head)	*stream << " head";    if (foot)	*stream << " foot";    *stream << endl << ind << "cspans:";    for ( unsigned int i = 0; i < columns.size(); i++ )	*stream << " " << columns[i].span;    *stream << endl << ind;    RenderBlock::dump(stream,ind);}#endif// --------------------------------------------------------------------------RenderTableSection::RenderTableSection(DOM::NodeImpl* node)    : RenderBox(node){    // init RenderObject attributes    setInline(false);   // our object is not Inline    cCol = 0;    cRow = -1;    needCellRecalc = false;}RenderTableSection::~RenderTableSection(){    clearGrid();}void RenderTableSection::detach(){    // recalc cell info because RenderTable has unguarded pointers    // stored that point to this RenderTableSection.    if (table())        table()->setNeedSectionRecalc();    RenderBox::detach();}void RenderTableSection::setStyle(RenderStyle* _style){    // we don't allow changing this one    if (style())        _style->setDisplay(style()->display());    else if (_style->display() != TABLE_FOOTER_GROUP && _style->display() != TABLE_HEADER_GROUP)        _style->setDisplay(TABLE_ROW_GROUP);    RenderBox::setStyle(_style);}void RenderTableSection::addChild(RenderObject *child, RenderObject *beforeChild){#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(TableSection)::addChild( " << child->renderName()  << ", beforeChild=" <<                       (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;#endif    RenderObject *row = child;    if (child->element() && child->element()->id() == ID_FORM) {        RenderContainer::addChild(child,beforeChild);        return;    }        if ( !child->isTableRow() ) {        if( !beforeChild )            beforeChild = lastChild();        if( beforeChild && beforeChild->isAnonymous() )            row = beforeChild;        else {	    RenderObject *lastBox = beforeChild;	    while ( lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableRow() )		lastBox = lastBox->parent();	    if ( lastBox && lastBox->isAnonymous() ) {		lastBox->addChild( child, beforeChild );		return;	    } else {		//kdDebug( 6040 ) << "creating anonymous table row" << endl;		row = new (renderArena()) RenderTableRow(document() /* anonymous table */);		RenderStyle *newStyle = new (renderArena()) RenderStyle();		newStyle->inheritFrom(style());		newStyle->setDisplay( TABLE_ROW );		row->setStyle(newStyle);		addChild(row, beforeChild);	    }        }        row->addChild(child);        child->setNeedsLayoutAndMinMaxRecalc();        return;    }    if (beforeChild)	setNeedCellRecalc();    cRow++;    cCol = 0;    ensureRows( cRow+1 );    if (!beforeChild) {        grid[cRow].height = child->style()->height();        if ( grid[cRow].height.type == Relative )            grid[cRow].height = Length();    }    RenderContainer::addChild(child,beforeChild);}void RenderTableSection::ensureRows( int numRows ){    int nRows = grid.size();    int nCols = table()->numEffCols();    if ( numRows > nRows ) {	grid.resize( numRows );	for ( int r = nRows; r < numRows; r++ ) {	    grid[r].row = new Row( nCols );	    grid[r].row->fill( 0 );	    grid[r].baseLine = 0;	    grid[r].height = Length();	}    }}void RenderTableSection::addCell( RenderTableCell *cell ){    int rSpan = cell->rowSpan();    int cSpan = cell->colSpan();    QMemArray<RenderTable::ColumnStruct> &columns = table()->columns;    int nCols = columns.size();    // ### mozilla still seems to do the old HTML way, even for strict DTD    // (see the annotation on table cell layouting in the CSS specs and the testcase below:    // <TABLE border>    // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4    // <TR><TD colspan="2">5    // </TABLE>#if 0    // find empty space for the cell    bool found = false;    while ( !found ) {	found = true;	while ( cCol < nCols && cellAt( cRow, cCol ) )	    cCol++;	int pos = cCol;	int span = 0;	while ( pos < nCols && span < cSpan ) {	    if ( cellAt( cRow, pos ) ) {		found = false;		cCol = pos;		break;	    }	    span += columns[pos].span;	    pos++;	}    }#else    while ( cCol < nCols && cellAt( cRow, cCol ) )	cCol++;#endif//       qDebug("adding cell at %d/%d span=(%d/%d)",  cRow, cCol, rSpan, cSpan );    if ( rSpan == 1 ) {	// we ignore height settings on rowspan cells	Length height = cell->style()->height();	if ( height.value > 0 || (height.type == Relative && height.value >= 0) ) {	    Length cRowHeight = grid[cRow].height;	    switch( height.type ) {	    case Percent:		if ( !(cRowHeight.type == Percent) ||		     ( cRowHeight.type == Percent && cRowHeight.value < height.value ) )		    grid[cRow].height = height;		     break;	    case Fixed:		if ( cRowHeight.type < Percent ||		     ( cRowHeight.type == Fixed && cRowHeight.value < height.value ) )		    grid[cRow].height = height;		break;	    case Relative:#if 0		// we treat this as variable. This is correct according to HTML4, as it only specifies length for the height.		if ( cRowHeight.type == Variable ||		     ( cRowHeight.type == Relative && cRowHeight.value < height.value ) )		     grid[cRow].height = height;		     break;#endif	    default:		break;	    }	}    }    // make sure we have enough rows    ensureRows( cRow + rSpan );    int col = cCol;    // tell the cell where it is    RenderTableCell *set = cell;    while ( cSpan ) {	int currentSpan;	if ( cCol >= nCols ) {	    table()->appendColumn( cSpan );	    currentSpan = cSpan;	} else {	    if ( cSpan < columns[cCol].span )		table()->splitColumn( cCol, cSpan );	    currentSpan = columns[cCol].span;	}	int r = 0;	while ( r < rSpan ) {	    if ( !cellAt( cRow + r, cCol ) ) {// 		qDebug("    adding cell at %d, %d",  cRow + r, cCol );		cellAt( cRow + r, cCol ) = set;	    }	    r++;	}	cCol++;	cSpan -= currentSpan;	set = (RenderTableCell *)-1;    }    if ( cell ) {	cell->setRow( cRow );	cell->setCol( table()->effColToCol( col ) );    }}void RenderTableSection::setCellWidths(){#ifdef DEBUG_LAYOUT    kdDebug( 6040 ) << renderName() << "(Table, this=0x" << this << ")::setCellWidths()" << endl;#endif    QMemArray<int> &columnPos = table()->columnPos;    int rows = grid.size();    for ( int i = 0; i < rows; i++ ) {	Row &row = *grid[i].row;	int cols = row.size();	for ( int j = 0; j < cols; j++ ) {	    RenderTableCell *cell = row[j];// 	    qDebug("cell[%d,%d] = %p", i, j, cell );	    if ( !cell || cell == (RenderTableCell *)-1 )		continue;	    int endCol = j;	    int cspan = cell->colSpan();	    while ( cspan && endCol < cols ) {		cspan -= table()->columns[endCol].span;		endCol++;	    }	    int w = columnPos[endCol] - columnPos[j] - table()->hBorderSpacing();#ifdef DEBUG_LAYOUT	    kdDebug( 6040 ) << "setting width of cell " << cell << " " << cell->row() << "/" << cell->col() << " to " << w << " colspan=" << cell->colSpan() << " start=" << j << " end=" << endCol << endl;#endif	    int oldWidth = cell->width();	    if ( w != oldWidth ) {		cell->setNeedsLayout(true);		cell->setWidth( w );	    }	}    }}void RenderTableSection::calcRowHeight(){    int indx;    RenderTableCell *cell;    int totalRows = grid.size();    int spacing = table()->vBorderSpacing();    rowPos.resize( totalRows + 1 );    rowPos[0] = spacing;    for ( int r = 0; r < totalRows; r++ ) {	rowPos[r+1] = 0;	int baseline=0;	int bdesc = 0;// 	qDebug("height of row %d is %d/%d", r, grid[r].height.value, grid[r].height.type );	int ch = grid[r].height.minWidth( 0 );	int pos = rowPos[ r+1 ] + ch + spacing;	if ( pos > rowPos[r+1] )	    rowPos[r+1] = pos;	Row *row = grid[r].row;	int totalCols = row->size();	int totalRows = grid.size();	for ( int c = 0; c < totalCols; c++ ) {	    cell = cellAt(r, c);	    if ( !cell || cell == (RenderTableCell *)-1 )		continue;	    if ( r < totalRows - 1 && cellAt(r+1, c) == cell )		continue;	    if ( ( indx = r - cell->rowSpan() + 1 ) < 0 )		indx = 0;            if (cell->getCellPercentageHeight()) {                cell->setCellPercentageHeight(0);                cell->setChildNeedsLayout(true, false);                cell->layoutIfNeeded();            }                        // Explicit heights use the border box in quirks mode.  In strict mode do the right            // thing and actually add in the border and padding.	    ch = cell->style()->height().width(0) +                 (cell->style()->htmlHacks() ? 0 : (cell->paddingTop() + cell->paddingBottom() +                                                   cell->borderTop() + cell->borderBottom()));	    if (cell->height() > ch)		ch = cell->height();            pos = rowPos[ indx ] + ch + spacing;	    if ( pos > rowPos[r+1] )		rowPos[r+1] = pos;	    // find out the baseline	    EVerticalAlign va = cell->style()->verticalAlign();	    if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP		|| va == SUPER || va == SUB)	    {		int b=cell->baselinePosition();		if (b>baseline)		    baseline=b;		int td = rowPos[ indx ] + ch - b;		if (td>bdesc)		    bdesc = td;	    }	}	//do we have baseline aligned elements?	if (baseline) {	    // increase rowheight if baseline requires	    int bRowPos = baseline + bdesc  + spacing ; // + 2*padding	    if (rowPos[r+1]<bRowPos)		rowPos[r+1]=bRowPos;	    grid[r].baseLine = baseline;	}	if ( rowPos[r+1] < rowPos[r] )	    rowPos[r+1] = rowPos[r];//   	qDebug("rowpos(%d)=%d",  r, rowPos[r] );    }}int RenderTableSection::layoutRows( int toAdd ){    int rHeight;    int rindx;    int totalRows = grid.size();    int hspacing = table()->hBorderSpacing();    int vspacing = table()->vBorderSpacing();        if (toAdd && totalRows && (rowPos[totalRows] || !nextSibling())) {	int totalHeight = rowPos[totalRows] + toAdd;// 	qDebug("layoutRows: totalHeight = %d",  totalHeight );        int dh = toAdd;	int totalPercent = 0;	int numVariable = 0;	for ( int r = 0; r < totalRows; r++ ) {	    if ( grid[r].height.type == Variable )		numVariable++;	    else if ( grid[r].height.type == Percent )		totalPercent += grid[r].height.value;	}	if ( totalPercent ) {// 	    qDebug("distributing %d over percent rows totalPercent=%d", dh,  totalPercent );	    // try to satisfy percent	    int add = 0;	    if ( totalPercent > 100 )		totalPercent = 100;	    int rh = rowPos[1]-rowPos[0];	    for ( int r = 0; r < totalRows; r++ ) {		if ( totalPercent > 0 && grid[r].height.type == Percent ) {		    int toAdd = kMin(dh, (totalHeight * grid[r].height.value / 100)-rh);                    // If toAdd is negative, then we don't want to shrink the row (this bug                    // affected Outlook Web Access).                    toAdd = QMAX(0, toAdd);		    add += toAdd;		    dh -= toAdd;		    totalPercent -= grid[r].height.value;// 		    qDebug( "adding %d to row %d", toAdd, r );		}		if ( r < totalRows-1 )		    rh = rowPos[r+2] - rowPos[r+1];                rowPos[r+1] += add;	    }	}	if ( numVariable ) {	    // distribute over variable cols// 	    qDebug("distributing %d over variable rows numVariable=%d", dh,  numVariable );	    int add = 0;

⌨️ 快捷键说明

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