[webkit-changes] cvs commit: WebCore/khtml/rendering
render_table.cpp render_table.h table_layout.cpp
Beth
bdakin at opensource.apple.com
Thu Nov 17 10:44:55 PST 2005
bdakin 05/11/17 10:44:55
Modified: . ChangeLog
khtml/rendering render_table.cpp render_table.h
table_layout.cpp
Log:
Bug #:
Revision Changes Path
1.376 +45 -0 WebCore/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/root/WebCore/ChangeLog,v
retrieving revision 1.375
retrieving revision 1.376
diff -u -r1.375 -r1.376
--- ChangeLog 17 Nov 2005 03:37:07 -0000 1.375
+++ ChangeLog 17 Nov 2005 18:44:50 -0000 1.376
@@ -1,3 +1,48 @@
+2005-11-17 Beth Dakin <bdakin at apple.com>
+
+ Reviewed by Darin
+
+ Fix for <rdar://problem/3871165> text box in nested table
+ disappears when you click on it (3452) (Safari PSOFT: US
+ EDU PS8: Lead List searches)
+
+ Table cells that are in an overlap of a rowspan and a colspan
+ were not always being repainted correctly. This is because our
+ previous implementation had no way for a cell to keep track of
+ both its rowspan and its colspan. This patch maintains the old
+ way of dealing with rowspan and introduces CellStruct for dealing
+ with colspan. CellStruct is a structure that contains a
+ RenderTableCell and a boolean value that is true if the cell is in
+ a colspan.
+
+ * khtml/rendering/render_table.cpp:
+ (RenderTable::splitColumn): The section grid now returns a CellStruct.
+ (RenderTable::appendColumn): Same as above, and cellAt() also returns
+ a CellStruct and needs to be set appropriately.
+ (RenderTable::cellAbove): cellAt() now returns a CellStruct.
+ (RenderTable::cellBelow): Same.
+ (RenderTable::cellLeft): Same.
+ (RenderTable::cellRight): Same.
+ (RenderTableSection::ensureRows): Create empty CellStruct to fill the
+ grid.
+ (RenderTableSection::addCell): cellAt() now returns a CellStruct. This
+ is also where the change in behavior is to fix
+ the bug.
+ (RenderTableSection::setCellWidths): cellAt() now returns a CellStruct.
+ (RenderTableSection::calcRowHeight): Same.
+ (RenderTableSection::layoutRows): Same.
+ (RenderTableSection::paint): Same.
+ (RenderTableSection::dump): Same.
+ * khtml/rendering/render_table.h:
+ (khtml::RenderTableSection::cellAt): Same.
+ * khtml/rendering/table_layout.cpp:
+ (AutoTableLayout::recalcColumn): Same.
+ (AutoTableLayout::calcEffectiveWidth): Removed reference to
+ (RenderTableCell *)-1 because that is now
+ removed, and a cell will never be in a colspan
+ in this function anyway.
+ (AutoTableLayout::insertSpanCell): Same.
+
2005-11-16 Justin Garcia <justin.garcia at apple.com>
Reviewed by darin
1.138 +92 -107 WebCore/khtml/rendering/render_table.cpp
Index: render_table.cpp
===================================================================
RCS file: /cvs/root/WebCore/khtml/rendering/render_table.cpp,v
retrieving revision 1.137
retrieving revision 1.138
diff -u -r1.137 -r1.138
--- render_table.cpp 2 Nov 2005 08:52:46 -0000 1.137
+++ render_table.cpp 17 Nov 2005 18:44:54 -0000 1.138
@@ -486,32 +486,30 @@
columns.resize( oldSize + 1 );
int oldSpan = columns[pos].span;
// qDebug("splitColumn( %d,%d ), oldSize=%d, oldSpan=%d", pos, firstSpan, oldSize, oldSpan );
- KHTMLAssert( oldSpan > firstSpan );
+ KHTMLAssert(oldSpan > firstSpan);
columns[pos].span = firstSpan;
- memmove( columns.data()+pos+1, columns.data()+pos, (oldSize-pos)*sizeof(ColumnStruct) );
+ 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() ) {
+ while (child) {
+ if (child->isTableSection()) {
RenderTableSection *section = static_cast<RenderTableSection *>(child);
- int size = section->numRows();
- int row = 0;
- if ( section->cCol > pos )
+ if (section->cCol > pos)
section->cCol++;
- while ( row < size ) {
- section->grid[row].row->resize( oldSize+1 );
+ int size = section->numRows();
+ for (int row = 0; row < size; ++row) {
+ 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++;
+ memmove(r.data() + pos + 1, r.data() + pos, (oldSize - pos) * sizeof(RenderTableSection::CellStruct));
+ r[pos + 1].cell = 0;
+ r[pos + 1].inColSpan = r[pos].inColSpan || r[pos].cell;
}
}
child = child->nextSibling();
}
- columnPos.resize( numEffCols()+1 );
+ columnPos.resize(numEffCols() + 1);
setNeedsLayoutAndMinMaxRecalc();
}
@@ -519,29 +517,27 @@
{
// easy case.
int pos = columns.size();
-// qDebug("appendColumn( %d ), size=%d", span, pos );
int newSize = pos + 1;
- columns.resize( newSize );
+ 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() ) {
+ while (child) {
+ if (child->isTableSection()) {
RenderTableSection *section = static_cast<RenderTableSection *>(child);
int size = section->numRows();
- int row = 0;
- while ( row < size ) {
- section->grid[row].row->resize( newSize );
- section->cellAt( row, pos ) = 0;
- row++;
+ for (int row = 0; row < size; ++row) {
+ section->grid[row].row->resize(newSize);
+ RenderTableSection::CellStruct& c = section->cellAt(row, pos);
+ c.cell = 0;
+ c.inColSpan = false;
}
}
child = child->nextSibling();
}
- columnPos.resize( numEffCols()+1 );
+ columnPos.resize(numEffCols() + 1);
setNeedsLayoutAndMinMaxRecalc();
}
@@ -700,13 +696,13 @@
// 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;
+ RenderTableSection::CellStruct 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;
+ } while (!aboveCell.cell && aboveCell.inColSpan && effCol >=0);
+ return aboveCell.cell;
} else {
return 0;
}
@@ -739,13 +735,13 @@
// 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;
+ RenderTableSection::CellStruct 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;
+ } while (!belowCell.cell && belowCell.inColSpan && effCol >=0);
+ return belowCell.cell;
} else {
return 0;
}
@@ -759,12 +755,12 @@
return 0;
// If we hit a colspan back up to a real cell.
- RenderTableCell* prevCell;
+ RenderTableSection::CellStruct prevCell;
do {
prevCell = section->cellAt(cell->row(), effCol-1);
effCol--;
- } while (prevCell == (RenderTableCell *)-1 && effCol >=0);
- return (prevCell == (RenderTableCell *)-1) ? 0 : prevCell;
+ } while (!prevCell.cell && prevCell.inColSpan && effCol >=0);
+ return prevCell.cell;
}
RenderTableCell* RenderTable::cellRight(const RenderTableCell* cell) const
@@ -772,8 +768,7 @@
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;
+ return cell->section()->cellAt(cell->row(), effCol).cell;
}
RenderBlock* RenderTable::firstLineBlock() const
@@ -912,9 +907,12 @@
gridRows = numRows;
int nCols = table()->numEffCols();
+ CellStruct emptyCellStruct;
+ emptyCellStruct.cell = 0;
+ emptyCellStruct.inColSpan = false;
for (int r = nRows; r < numRows; r++ ) {
grid[r].row = new Row(nCols);
- grid[r].row->fill(0);
+ grid[r].row->fill(emptyCellStruct);
grid[r].baseLine = 0;
grid[r].height = Length();
}
@@ -936,31 +934,9 @@
// <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 );
+ while (cCol < nCols && (cellAt(cRow, cCol).cell || cellAt(cRow, cCol).inColSpan))
+ cCol++;
if ( rSpan == 1 ) {
// we ignore height settings on rowspan cells
@@ -998,32 +974,35 @@
int col = cCol;
// tell the cell where it is
- RenderTableCell *set = cell;
- while ( cSpan ) {
+ CellStruct currentCell;
+ currentCell.cell = cell;
+ currentCell.inColSpan = false;
+ while (cSpan) {
int currentSpan;
- if ( cCol >= nCols ) {
- table()->appendColumn( cSpan );
+ if (cCol >= nCols) {
+ table()->appendColumn(cSpan);
currentSpan = cSpan;
} else {
- if ( cSpan < columns[cCol].span )
- table()->splitColumn( cCol, cSpan );
+ 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++;
+
+ for (int r = 0; r < rSpan; r++) {
+ CellStruct& c = cellAt(cRow + r, cCol);
+ if (currentCell.cell && !c.cell)
+ c.cell = currentCell.cell;
+ if (currentCell.inColSpan)
+ c.inColSpan = true;
}
cCol++;
cSpan -= currentSpan;
- set = (RenderTableCell *)-1;
+ currentCell.cell = 0;
+ currentCell.inColSpan = true;
}
- if ( cell ) {
- cell->setRow( cRow );
- cell->setCol( table()->effColToCol( col ) );
+ if (cell) {
+ cell->setRow(cRow);
+ cell->setCol(table()->effColToCol(col));
}
}
@@ -1041,13 +1020,14 @@
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 )
+ CellStruct current = row[j];
+ RenderTableCell *cell = current.cell;
+
+ if (!cell)
continue;
int endCol = j;
int cspan = cell->colSpan();
- while ( cspan && endCol < cols ) {
+ while (cspan && endCol < cols) {
cspan -= table()->columns[endCol].span;
endCol++;
}
@@ -1092,14 +1072,15 @@
int totalCols = row->size();
int totalRows = gridRows;
- for ( int c = 0; c < totalCols; c++ ) {
- cell = cellAt(r, c);
- if ( !cell || cell == (RenderTableCell *)-1 )
+ for (int c = 0; c < totalCols; c++) {
+ CellStruct current = cellAt(r, c);
+ cell = current.cell;
+ if (!cell || current.inColSpan)
continue;
- if ( r < totalRows - 1 && cellAt(r+1, c) == cell )
+ if (r < totalRows - 1 && cellAt(r + 1, c).cell == cell)
continue;
- if ( ( indx = r - cell->rowSpan() + 1 ) < 0 )
+ if ((indx = r - cell->rowSpan() + 1) < 0)
indx = 0;
if (cell->overrideSize() != -1) {
@@ -1230,19 +1211,21 @@
int leftOffset = hspacing;
int nEffCols = table()->numEffCols();
- for ( int r = 0; r < totalRows; r++ )
+ for (int r = 0; r < totalRows; r++)
{
Row *row = grid[r].row;
int totalCols = row->size();
- for ( int c = 0; c < nEffCols; c++ )
+ for (int c = 0; c < nEffCols; c++)
{
- RenderTableCell *cell = cellAt(r, c);
- if (!cell || cell == (RenderTableCell *)-1 )
+ CellStruct current = cellAt(r, c);
+ RenderTableCell* cell = current.cell;
+
+ if (!cell)
continue;
- if ( r < totalRows - 1 && cell == cellAt(r+1, c) )
+ if (r < totalRows - 1 && cell == cellAt(r + 1, c).cell)
continue;
- if ( ( rindx = r-cell->rowSpan()+1 ) < 0 )
+ if ((rindx = r-cell->rowSpan() + 1) < 0)
rindx = 0;
rHeight = rowPos[r+1] - rowPos[rindx] - vspacing;
@@ -1371,37 +1354,39 @@
}
for ( ; endrow > 0; endrow-- ) {
if ( ty + rowPos[endrow-1] <= y + h + os)
- break;
+ break;
}
unsigned int startcol = 0;
unsigned int endcol = totalCols;
if ( style()->direction() == LTR ) {
for ( ; startcol < totalCols; startcol++ ) {
if ( tx + table()->columnPos[startcol+1] >= x - os)
- break;
+ break;
}
for ( ; endcol > 0; endcol-- ) {
if ( tx + table()->columnPos[endcol-1] <= x + w + os)
break;
}
}
-
- if ( startcol < endcol ) {
+
+ if (startcol < endcol) {
// draw the cells
for ( unsigned int r = startrow; r < endrow; r++ ) {
unsigned int c = startcol;
// since a cell can be -1 (indicating a colspan) we might have to search backwards to include it
- while ( c && cellAt( r, c ) == (RenderTableCell *)-1 )
+ while (c && cellAt(r, c).inColSpan)
c--;
for ( ; c < endcol; c++ ) {
- RenderTableCell *cell = cellAt(r, c);
- if (!cell || cell == (RenderTableCell *)-1 || (cell->layer() && i.phase != PaintActionCollapsedTableBorders))
+ CellStruct current = cellAt(r, c);
+ RenderTableCell *cell = current.cell;
+
+ if (!cell || (cell->layer() && i.phase != PaintActionCollapsedTableBorders))
continue;
// Cells must always paint in the order in which they appear taking into account
// their upper left originating row/column. For cells with rowspans, avoid repainting
// if we've already seen the cell.
- if (r > startrow && (cellAt(r-1, c) == cell))
+ if (r > startrow && (cellAt(r-1, c).cell == cell))
continue;
#ifdef TABLE_PRINT
@@ -1455,13 +1440,13 @@
void RenderTableSection::dump(QTextStream *stream, QString ind) const
{
*stream << endl << ind << "grid=(" << grid.size() << "," << table()->numEffCols() << ")" << endl << ind;
- for ( unsigned int r = 0; r < grid.size(); r++ ) {
- for ( int c = 0; c < table()->numEffCols(); c++ ) {
- if ( cellAt( r, c ) && cellAt( r, c ) != (RenderTableCell *)-1 )
- *stream << "(" << cellAt( r, c )->row() << "," << cellAt( r, c )->col() << ","
- << cellAt(r, c)->rowSpan() << "," << cellAt(r, c)->colSpan() << ") ";
+ for (unsigned int r = 0; r < grid.size(); r++) {
+ for (int c = 0; c < table()->numEffCols(); c++) {
+ if (cellAt( r, c).cell && !cellAt(r, c).inColSpan)
+ *stream << "(" << cellAt(r, c).cell->row() << "," << cellAt(r, c).cell->col() << ","
+ << cellAt(r, c).cell->rowSpan() << "," << cellAt(r, c).cell->colSpan() << ") ";
else
- *stream << cellAt( r, c ) << "null cell ";
+ *stream << cellAt(r, c).cell << "null cell ";
}
*stream << endl << ind;
}
1.49 +9 -5 WebCore/khtml/rendering/render_table.h
Index: render_table.h
===================================================================
RCS file: /cvs/root/WebCore/khtml/rendering/render_table.h,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- render_table.h 25 Oct 2005 22:26:30 -0000 1.48
+++ render_table.h 17 Nov 2005 18:44:54 -0000 1.49
@@ -229,18 +229,22 @@
RenderTable *table() const { return static_cast<RenderTable *>(parent()); }
- typedef QMemArray<RenderTableCell *> Row;
+ struct CellStruct {
+ RenderTableCell *cell;
+ bool inColSpan; // true for columns after the first in a colspan
+ };
+ typedef QMemArray<CellStruct> Row;
struct RowStruct {
Row *row;
int baseLine;
Length height;
};
- RenderTableCell *&cellAt( int row, int col ) {
- return (*(grid[row].row))[col];
+ CellStruct& cellAt(int row, int col) {
+ return (*grid[row].row)[col];
}
- RenderTableCell *cellAt( int row, int col ) const {
- return (*(grid[row].row))[col];
+ const CellStruct& cellAt(int row, int col) const {
+ return (*grid[row].row)[col];
}
virtual void paint(PaintInfo& i, int tx, int ty);
1.26 +19 -17 WebCore/khtml/rendering/table_layout.cpp
Index: table_layout.cpp
===================================================================
RCS file: /cvs/root/WebCore/khtml/rendering/table_layout.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- table_layout.cpp 3 Oct 2005 21:12:42 -0000 1.25
+++ table_layout.cpp 17 Nov 2005 18:44:54 -0000 1.26
@@ -20,7 +20,7 @@
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
- * $Id: table_layout.cpp,v 1.25 2005/10/03 21:12:42 mjs Exp $
+ * $Id: table_layout.cpp,v 1.26 2005/11/17 18:44:54 bdakin Exp $
*/
#include "config.h"
#include "table_layout.h"
@@ -370,35 +370,37 @@
RenderTableCell *fixedContributor = 0;
RenderTableCell *maxContributor = 0;
- while ( child ) {
- if ( child->isTableSection() ) {
+ while (child) {
+ if (child->isTableSection()) {
RenderTableSection *section = static_cast<RenderTableSection *>(child);
int numRows = section->numRows();
RenderTableCell *last = 0;
for ( int i = 0; i < numRows; i++ ) {
- RenderTableCell *cell = section->cellAt( i, effCol );
- if ( cell == (RenderTableCell *)-1 )
+ RenderTableSection::CellStruct current = section->cellAt(i, effCol);
+ RenderTableCell *cell = current.cell;
+
+ if (current.inColSpan)
continue;
- if ( cell && cell->colSpan() == 1 ) {
+ if (cell && cell->colSpan() == 1) {
// A cell originates in this column. Ensure we have
// a min/max width of at least 1px for this column now.
l.minWidth = kMax(l.minWidth, 1);
l.maxWidth = kMax(l.maxWidth, 1);
- if ( !cell->minMaxKnown() )
+ if (!cell->minMaxKnown())
cell->calcMinMaxWidth();
- if ( cell->minWidth() > l.minWidth )
+ if (cell->minWidth() > l.minWidth)
l.minWidth = cell->minWidth();
- if ( cell->maxWidth() > l.maxWidth ) {
+ if (cell->maxWidth() > l.maxWidth) {
l.maxWidth = cell->maxWidth();
maxContributor = cell;
}
Length w = cell->style()->width();
- if ( w.value > 32760 )
+ if (w.value > 32760)
w.value = 32760;
- if ( w.value < 0 )
+ if (w.value < 0)
w.value = 0;
- switch( w.type ) {
+ switch(w.type) {
case Fixed:
// ignore width=0
if ( w.value > 0 && (int)l.width.type != Percent ) {
@@ -419,17 +421,17 @@
break;
case Percent:
hasPercent = true;
- if ( w.value > 0 && (l.width.type != Percent || w.value > l.width.value ) )
+ if (w.value > 0 && (l.width.type != Percent || w.value > l.width.value ))
l.width = w;
break;
case Relative:
- if ( w.type == Auto || (w.type == Relative && w.value > l.width.value ) )
+ if (w.type == Auto || (w.type == Relative && w.value > l.width.value ))
l.width = w;
default:
break;
}
} else {
- if ( cell && (!effCol || section->cellAt( i, effCol-1 ) != cell) ) {
+ if (cell && (!effCol || section->cellAt(i, effCol-1).cell != cell)) {
// This spanning cell originates in this column. Ensure we have
// a min/max width of at least 1px for this column now.
l.minWidth = kMax(l.minWidth, 1);
@@ -626,7 +628,7 @@
for ( unsigned int i = 0; i < spanCells.size(); i++ ) {
RenderTableCell *cell = spanCells[i];
- if ( !cell || cell == (RenderTableCell *)-1 )
+ if (!cell)
break;
int span = cell->colSpan();
@@ -816,7 +818,7 @@
*/
void AutoTableLayout::insertSpanCell( RenderTableCell *cell )
{
- if ( !cell || cell == (RenderTableCell *)-1 || cell->colSpan() == 1 )
+ if (!cell || cell->colSpan() == 1)
return;
// qDebug("inserting span cell %p with span %d", cell, cell->colSpan() );
More information about the webkit-changes
mailing list