📄 render_table.cpp
字号:
&& shouldPaintBackgroundOrBorder() && style()->visibility() == VISIBLE) paintBoxDecorations(pI, _tx, _ty); if ( pI.phase == PaintActionElementBackground ) return; PaintAction oldphase = pI.phase; if ( pI.phase == PaintActionChildBackgrounds ) pI.phase = PaintActionChildBackground; for( RenderObject *child = firstChild(); child; child = child->nextSibling()) if ( child->isTableSection() || child == tCaption ) child->paint( pI, _tx, _ty ); if (collapseBorders() && (pI.phase == PaintActionElementBackground || pI.phase == PaintActionChildBackground) && style()->visibility() == VISIBLE) { // Collect all the unique border styles that we want to paint in a sorted list. Once we // have all the styles sorted, we then do individual passes, painting each style of border // from lowest precedence to highest precedence. pI.phase = PaintActionCollapsedTableBorders; QValueList<CollapsedBorderValue> borderStyles; collectBorders(borderStyles);#if 0 QString m; for (uint i = 0; i < borderStyles.count(); i++) m += QString("%1 ").arg((*borderStyles.at(i)).width()); kdDebug(6040) << m << endl;#endif QValueListIterator<CollapsedBorderValue> it = borderStyles.begin(); QValueListIterator<CollapsedBorderValue> end = borderStyles.end(); for (; it != end; ++it) { m_currentBorder = &*it; for (RenderObject *child = firstChild(); child; child = child->nextSibling()) { if (child->isTableSection()) child->paint(pI, _tx, _ty); } } m_currentBorder = 0; } pI.phase = oldphase;#ifdef BOX_DEBUG outlineBox(p, _tx, _ty, "blue");#endif}void RenderTable::paintBoxDecorations(PaintInfo &pI, int _tx, int _ty){ int w = width(); int h = height() + borderTopExtra() + borderBottomExtra(); _ty -= borderTopExtra(); int my = kMax(_ty,pI.r.y()); int mh; if (_ty<pI.r.y()) mh= kMax(0,h-(pI.r.y()-_ty)); else mh = kMin(pI.r.height(),h); paintBackground(pI.p, style()->backgroundColor(), style()->backgroundLayers(), my, mh, _tx, _ty, w, h); if (style()->hasBorder() && !collapseBorders()) paintBorder(pI.p, _tx, _ty, w, h, style());}void RenderTable::calcMinMaxWidth(){ KHTMLAssert( !minMaxKnown() ); if ( needSectionRecalc ) recalcSections();#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << "(Table " << this << ")::calcMinMaxWidth()" << endl;#endif tableLayout->calcMinMaxWidth(); if (tCaption && tCaption->minWidth() > m_minWidth) m_minWidth = tCaption->minWidth(); setMinMaxKnown();#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << " END: (Table " << this << ")::calcMinMaxWidth() min = " << m_minWidth << " max = " << m_maxWidth << endl;#endif}void RenderTable::close(){// kdDebug( 6040 ) << "RenderTable::close()" << endl; setNeedsLayoutAndMinMaxRecalc();}int RenderTable::borderTopExtra(){ if (tCaption && tCaption->style()->captionSide()!=CAPBOTTOM) return -(tCaption->height() + tCaption->marginBottom() + tCaption->marginTop()); else return 0;}int RenderTable::borderBottomExtra(){ if (tCaption && tCaption->style()->captionSide()==CAPBOTTOM) return -(tCaption->height() + tCaption->marginBottom() + tCaption->marginTop()); else return 0;}void RenderTable::splitColumn( int pos, int firstSpan ){ // we need to add a new columnStruct int oldSize = columns.size(); columns.resize( oldSize + 1 ); int oldSpan = columns[pos].span;// qDebug("splitColumn( %d,%d ), oldSize=%d, oldSpan=%d", pos, firstSpan, oldSize, oldSpan ); KHTMLAssert( oldSpan > firstSpan ); columns[pos].span = firstSpan; memmove( columns.data()+pos+1, columns.data()+pos, (oldSize-pos)*sizeof(ColumnStruct) ); columns[pos+1].span = oldSpan - firstSpan; // change width of all rows. RenderObject *child = firstChild(); while ( child ) { if ( child->isTableSection() ) { RenderTableSection *section = static_cast<RenderTableSection *>(child); int size = section->grid.size(); int row = 0; if ( section->cCol > pos ) section->cCol++; while ( row < size ) { section->grid[row].row->resize( oldSize+1 ); RenderTableSection::Row &r = *section->grid[row].row; memmove( r.data()+pos+1, r.data()+pos, (oldSize-pos)*sizeof( RenderTableCell * ) );// qDebug("moving from %d to %d, num=%d", pos, pos+1, (oldSize-pos-1) ); r[pos+1] = r[pos] ? (RenderTableCell *)-1 : 0; row++; } } child = child->nextSibling(); } columnPos.resize( numEffCols()+1 ); setNeedsLayoutAndMinMaxRecalc();}void RenderTable::appendColumn( int span ){ // easy case. int pos = columns.size();// qDebug("appendColumn( %d ), size=%d", span, pos ); int newSize = pos + 1; columns.resize( newSize ); columns[pos].span = span; //qDebug("appending column at %d, span %d", pos, span ); // change width of all rows. RenderObject *child = firstChild(); while ( child ) { if ( child->isTableSection() ) { RenderTableSection *section = static_cast<RenderTableSection *>(child); int size = section->grid.size(); int row = 0; while ( row < size ) { section->grid[row].row->resize( newSize ); section->cellAt( row, pos ) = 0; row++; } } child = child->nextSibling(); } columnPos.resize( numEffCols()+1 ); setNeedsLayoutAndMinMaxRecalc();}RenderTableCol *RenderTable::colElement( int col ) { if ( !has_col_elems ) return 0; RenderObject *child = firstChild(); int cCol = 0; while ( child ) { if ( child->isTableCol() ) { RenderTableCol *colElem = static_cast<RenderTableCol *>(child); int span = colElem->span(); if ( !colElem->firstChild() ) { cCol += span; if ( cCol > col ) return colElem; } RenderObject *next = child->firstChild(); if ( !next ) next = child->nextSibling(); if ( !next && child->parent()->isTableCol() ) next = child->parent()->nextSibling(); child = next; } else break; } return 0;}void RenderTable::recalcSections(){ tCaption = 0; head = foot = firstBody = 0; has_col_elems = false; RenderObject *child = firstChild(); // We need to get valid pointers to caption, head, foot and firstbody again while ( child ) { switch(child->style()->display()) { case TABLE_CAPTION: if ( !tCaption) { tCaption = static_cast<RenderBlock*>(child); tCaption->setNeedsLayout(true); } break; case TABLE_COLUMN: case TABLE_COLUMN_GROUP: has_col_elems = true; break; case TABLE_HEADER_GROUP: { RenderTableSection *section = static_cast<RenderTableSection *>(child); if ( !head ) head = section; else if ( !firstBody ) firstBody = section; if ( section->needCellRecalc ) section->recalcCells(); break; } case TABLE_FOOTER_GROUP: { RenderTableSection *section = static_cast<RenderTableSection *>(child); if ( !foot ) foot = section; else if ( !firstBody ) firstBody = section; if ( section->needCellRecalc ) section->recalcCells(); break; } case TABLE_ROW_GROUP: { RenderTableSection *section = static_cast<RenderTableSection *>(child); if ( !firstBody ) firstBody = section; if ( section->needCellRecalc ) section->recalcCells(); } default: break; } child = child->nextSibling(); } needSectionRecalc = false; setNeedsLayout(true);}RenderObject* RenderTable::removeChildNode(RenderObject* child){ setNeedSectionRecalc(); return RenderContainer::removeChildNode( child );}int RenderTable::borderLeft() const{ if (collapseBorders()) { // FIXME: For strict mode, returning 0 is correct, since the table border half spills into the margin, // but I'm working to get this changed. For now, follow the spec. return 0; } return RenderBlock::borderLeft();}int RenderTable::borderRight() const{ if (collapseBorders()) { // FIXME: For strict mode, returning 0 is correct, since the table border half spills into the margin, // but I'm working to get this changed. For now, follow the spec. return 0; } return RenderBlock::borderRight();}int RenderTable::borderTop() const{ if (collapseBorders()) { // FIXME: For strict mode, returning 0 is correct, since the table border half spills into the margin, // but I'm working to get this changed. For now, follow the spec. return 0; } return RenderBlock::borderTop();}int RenderTable::borderBottom() const{ if (collapseBorders()) { // FIXME: For strict mode, returning 0 is correct, since the table border half spills into the margin, // but I'm working to get this changed. For now, follow the spec. return 0; } return RenderBlock::borderBottom();}RenderTableCell* RenderTable::cellAbove(const RenderTableCell* cell) const{ // Find the section and row to look in int r = cell->row(); RenderTableSection* section = 0; int rAbove = -1; if (r > 0) { // cell is not in the first row, so use the above row in its own section section = cell->section(); rAbove = r-1; } else { // cell is at top of a section, use last row in previous section for (RenderObject *prevSection = cell->section()->previousSibling(); prevSection && rAbove < 0; prevSection = prevSection->previousSibling()) { if (prevSection->isTableSection()) { section = static_cast<RenderTableSection *>(prevSection); if (section->numRows() > 0) rAbove = section->numRows()-1; } } } // Look up the cell in the section's grid, which requires effective col index if (section && rAbove >= 0) { int effCol = colToEffCol(cell->col()); RenderTableCell* aboveCell; // If we hit a span back up to a real cell. do { aboveCell = section->cellAt(rAbove, effCol); effCol--; } while (aboveCell == (RenderTableCell *)-1 && effCol >=0); return (aboveCell == (RenderTableCell *)-1) ? 0 : aboveCell; } else { return 0; }}RenderTableCell* RenderTable::cellBelow(const RenderTableCell* cell) const{ // Find the section and row to look in int r = cell->row() + cell->rowSpan() - 1; RenderTableSection* section = 0; int rBelow = -1; if (r < cell->section()->numRows()-1) { // The cell is not in the last row, so use the next row in the section. section = cell->section(); rBelow= r+1; } else { // The cell is at the bottom of a section. Use the first row in the next section. for (RenderObject* nextSection = cell->section()->nextSibling(); nextSection && rBelow < 0; nextSection = nextSection->nextSibling()) { if (nextSection->isTableSection()) { section = static_cast<RenderTableSection *>(nextSection); if (section->numRows() > 0) rBelow = 0; } } } // Look up the cell in the section's grid, which requires effective col index if (section && rBelow >= 0) { int effCol = colToEffCol(cell->col()); RenderTableCell* belowCell; // If we hit a colspan back up to a real cell. do { belowCell = section->cellAt(rBelow, effCol); effCol--; } while (belowCell == (RenderTableCell *)-1 && effCol >=0); return (belowCell == (RenderTableCell *)-1) ? 0 : belowCell; } else { return 0; }}RenderTableCell* RenderTable::cellLeft(const RenderTableCell* cell) const{ RenderTableSection* section = cell->section(); int effCol = colToEffCol(cell->col()); if (effCol == 0) return 0; // If we hit a colspan back up to a real cell. RenderTableCell* prevCell; do { prevCell = section->cellAt(cell->row(), effCol-1); effCol--; } while (prevCell == (RenderTableCell *)-1 && effCol >=0); return (prevCell == (RenderTableCell *)-1) ? 0 : prevCell;}RenderTableCell* RenderTable::cellRight(const RenderTableCell* cell) const{ int effCol = colToEffCol(cell->col()+cell->colSpan()); if (effCol >= numEffCols()) return 0; RenderTableCell* result = cell->section()->cellAt(cell->row(), effCol); return (result == (RenderTableCell*)-1) ? 0 : result;}#ifdef ENABLE_DUMPvoid RenderTable::dump(QTextStream &stream, const QString &ind) const{ RenderBlock::dump(stream, ind); if (tCaption) stream << " tCaption"; if (head) stream << " head"; if (foot) stream << " foot"; stream << " [cspans:"; for ( unsigned int i = 0; i < columns.size(); i++ ) stream << " " << columns[i].span; stream << "]";}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -