
Some parts of this message have been removed.
Learn more about Nabble's
security policy.
Hi list,
I had forgotten to submit this patch.
Now i believe it should be safe enough to commit.
Also I'm tired of this code, so I'll stop my work for now and start implementing the DOM Level 3 XPath specification.
Carlos
[tables.diff]
Index: html/html_tableimpl.cpp
===================================================================
--- html/html_tableimpl.cpp (revisión: 954616)
+++ html/html_tableimpl.cpp (copia de trabajo)
@@ -210,7 +210,7 @@
lastSection = section;
if ( index < 0 ) //append/last mode
return 0;
-
+
long rows = section->numRows();
if ( index >= rows ) {
section = 0;
@@ -428,7 +428,7 @@
return cellChanged;
}
-
+
void HTMLTableElementImpl::parseAttribute(AttributeImpl *attr)
{
// ### to CSS!!
@@ -910,14 +910,14 @@
// limit this to something not causing an overflow with short int
if(rSpan < 0 || rSpan > 1024) rSpan = 1;
if (renderer())
- renderer()->updateFromElement();
+ renderer()->updateFromElement();
break;
case ATTR_COLSPAN:
cSpan = attr->val() ? attr->val()->toInt() : 1;
// limit this to something not causing an overflow with short int
if(cSpan < 0 || cSpan > 1024) cSpan = 1;
if (renderer())
- renderer()->updateFromElement();
+ renderer()->updateFromElement();
break;
case ATTR_NOWRAP:
if (attr->val() != 0)
Index: rendering/render_table.cpp
===================================================================
--- rendering/render_table.cpp (revisión: 954616)
+++ rendering/render_table.cpp (copia de trabajo)
@@ -9,6 +9,7 @@
* (C) 2003 Apple Computer, Inc.
* (C) 2005 Allan Sandfeld Jensen (kde@...)
* (C) 2008 Germain Garand (germain@...)
+ * (C) 2009 Carlos Licea (carlos.licea@...
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -182,7 +183,7 @@
head = static_cast<RenderTableSection *>(child);
} else {
resetSectionPointerIfNotBefore(firstBody, beforeChild);
- if (!firstBody)
+ if (!firstBody)
firstBody = static_cast<RenderTableSection*>(child);
}
}
@@ -761,10 +762,10 @@
maxCols = sectionCols;
}
}
-
+
columns.resize(maxCols);
columnPos.resize(maxCols+1);
-
+
needSectionRecalc = false;
setNeedsLayout(true);
}
@@ -1028,6 +1029,7 @@
RenderTableSection::RenderTableSection(DOM::NodeImpl* node)
: RenderBox(node)
+ , containsSpansZero(false)
{
// init RenderObject attributes
setInline(false); // our object is not Inline
@@ -1156,7 +1158,7 @@
// <TR><TD colspan="2">5
// </TABLE>
while ( cCol < nCols && cellAt( cRow, cCol ) )
- cCol++;
+ ++cCol;
// qDebug("adding cell at %d/%d span=(%d/%d)", cRow, cCol, rSpan, cSpan );
@@ -1190,44 +1192,158 @@
}
}
+ //What:Postion the cell
+ //How: we take care of special case when colspan or rowspan equals 0
+ //after that position the cell, that is just to tell where is it and tell
+ //other cells where they can't be located (marking the cells as -1)
+ //later taking the span into account (and in other function) the cell is
+ //then painted (that's why we need to set the colspan and rowspan properly
+ //when any of them is cero
+
// make sure we have enough rows
- ensureRows( cRow + rSpan );
+ ensureRows( cRow + (rSpan? rSpan : 1 ) );
grid[cRow].rowRenderer = row;
int col = cCol;
// tell the cell where it is
RenderTableCell *set = cell;
+ kDebug()<<"row"<<cRow<<"col"<<cCol;
+// kDebug()<<"cSpan"<<cSpan<<"rSpan"<<rSpan;
+
+ //check wether we are in a column or in a row with span = 0
+ QList< int > columnsToAvoid;
+ if( containsSpansZero ) {
+ //Update any column which its last span update was in a previous column
+ int lowestCol = cellsWithColSpanZero.lowerBound( 0 ).key();
+ if( lowestCol < cCol ) {
+ //add the columns for this cell
+ if ( cCol >= nCols ) {
+ table()->appendColumn( cSpan );
+ nCols = columns.size();
+ }
+ //check and update all the cells that are updated to a previous column
+ while( lowestCol < nCols ) {
+ while( RenderTableCell* cell = cellsWithColSpanZero.take( lowestCol ) ) {
+ const int cellRow = cell->row();
+ const int cellRowSpan = cell->rowSpan();
+ int finalSpan = cell->colSpan();
+ for( int i = lowestCol; i < nCols; ++i ) {
+ if( !cellAt( cellRow, i ) ) {
+ cellAt( cellRow, i ) = (RenderTableCell *)-1;
+ }
+ ++finalSpan;
+ }
+ cell->setColSpan( finalSpan );
+ cellsWithColSpanZero.insertMulti( nCols, cell );
+ }
+ lowestCol = cellsWithColSpanZero.lowerBound( 0 ).key();
+ }
+ }
+ if( cellsWithRowSpanZero.contains( cRow ) ) {
+ //No need to check if we have enough columns, we already found the first cell
+ //when rowspan="0", and as such, we've already inserted it
+ while( RenderTableCell* cell = cellsWithRowSpanZero.take( cRow ) ) {
+ const int cellCol = cell->col();
+ const int finalCol = cellCol + cell->colSpan() - 1;
+ RenderTableCell* set = cell;
+ for( int i = cellCol; i <= finalCol; ++i ) {
+ if( !cellAt( cRow, i ) ) {
+ cellAt( cRow, i ) = set;
+ }
+ set = (RenderTableCell *)-1;
+ columnsToAvoid << i;
+ }
+ cell->setRowSpan( cell->rowSpan() + 1 );
+ //mark it to be inserted in next row
+ cellsWithRowSpanZero.insertMulti( cRow + 1, cell );
+ }
+ }
+ }
+
+ //Save the column if the its span is 0
+ if( !cSpan ) {
+ //Check if we only span in the current colgroup
+ if( RenderTableCol* colgroup = table()->colElement( cCol ) ) {
+ //Calculate the correct span and then handle the cell normally
+
+ int firstColumnOfColgroup = cCol;
+ while( --firstColumnOfColgroup >= 0 && colgroup == table()->colElement(firstColumnOfColgroup) ) ;
+ ++firstColumnOfColgroup;
+
+ int alreadyUsedSpan = 0;
+ RenderTableCell* colgroupCell = cellAt( cRow, firstColumnOfColgroup + alreadyUsedSpan );
+ while( firstColumnOfColgroup + alreadyUsedSpan < cCol ) {
+ alreadyUsedSpan += colgroupCell->colSpan();
+ colgroupCell = cellAt( cRow, firstColumnOfColgroup + alreadyUsedSpan );
+ }
+
+ const int finalSpan = colgroup->span() - alreadyUsedSpan;
+ cell->setColSpan( finalSpan );
+
+ //We know exactly the cSpan so we can handle the cell as a normal cell
+ //unless, of course, the rowspan is also 0
+ cSpan = finalSpan;
+ }
+ //or if we span in the whole table and mark it as inserted till
+ //this column and updated whenever another column is inserted
+ else {
+ //We define the proper span and let the other code handle it
+ const int finalSpan = nCols - cCol;
+ cSpan = finalSpan;
+
+ cell->setColSpan( finalSpan );
+
+ cellsWithColSpanZero.insertMulti( cCol + finalSpan - 1, cell );
+ containsSpansZero = true;
+ }
+ }
+
+ if( !rSpan ) {
+ //For now we span 1
+ rSpan = 1;
+ cell->setRowSpan( 1 );
+
+ //mark it to be inserted in next row
+ cellsWithRowSpanZero.insertMulti( cRow + 1, cell );
+ containsSpansZero = true;
+ }
+
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;
+ int currentSpan;
+ if ( cCol >= nCols ) {
+ table()->appendColumn( cSpan );
+ currentSpan = cSpan;
+ } else {
+ if ( cSpan < columns[cCol].span ) {
+ table()->splitColumn( cCol, cSpan );
+ }
+ currentSpan = columns[cCol].span;
+ }
+
+ while( columnsToAvoid.contains(cCol) )
+ ++cCol;
+
+ 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 ) );
+ cell->setRow( cRow );
+ cell->setCol( table()->effColToCol( col ) );
}
}
-
-
void RenderTableSection::setCellWidths()
{
#ifdef DEBUG_LAYOUT
@@ -1781,7 +1897,7 @@
if ( !cell || cell == (RenderTableCell *)-1 || nextrow && (*nextrow)[c] == cell )
continue;
RenderObject* rowr = cell->parent();
- int rtx = tx+rowr->xPos();
+ int rtx = tx+rowr->xPos();
int rty = ty+rowr->yPos();
#ifdef TABLE_PRINT
kDebug( 6040 ) << "painting cell " << r << "/" << c;
@@ -1826,23 +1942,25 @@
int RenderTableSection::numColumns() const
{
int result = 0;
-
+
for (int r = 0; r < numRows(); ++r) {
for (int c = result; c < table()->numEffCols(); ++c) {
if (cellAt(r, c))
result = c;
}
}
-
+
return result + 1;
}
-
+
void RenderTableSection::recalcCells()
{
cCol = 0;
cRow = -1;
clearGrid();
grid.resize( 0 );
+ cellsWithColSpanZero.clear();
+ cellsWithRowSpanZero.clear();
for (RenderObject *row = firstChild(); row; row = row->nextSibling()) {
if (row->isTableRow()) {
@@ -1854,6 +1972,7 @@
for (RenderObject *cell = row->firstChild(); cell; cell = cell->nextSibling())
if (cell->isTableCell())
addCell( static_cast<RenderTableCell *>(cell), static_cast<RenderTableRow *>(row) );
+
}
}
needCellRecalc = false;
@@ -2563,7 +2682,7 @@
RenderTableCol* colElt = table()->colElement(col() + (rtl ? colSpan() - 1 : 0), &startColEdge, &endColEdge);
if (colElt && (!rtl ? startColEdge : endColEdge)) {
result = compareBorders(result, CollapsedBorderValue(&colElt->style()->borderLeft(), BCOL));
- if (!result.exists())
+ if (!result.exists())
return result;
if (colElt->parent()->isTableCol() && (!rtl ? !colElt->previousSibling() : !colElt->nextSibling())) {
result = compareBorders(result, CollapsedBorderValue(&colElt->parent()->style()->borderLeft(), BCOLGROUP));
Index: rendering/render_table.h
===================================================================
--- rendering/render_table.h (revisión: 954616)
+++ rendering/render_table.h (copia de trabajo)
@@ -273,6 +273,12 @@
int numColumns() const;
+ //QMap< nextColumnToInsert, cell >
+ QMap< int, RenderTableCell* > cellsWithColSpanZero;
+ //QMap< nextRowToInsert, cell >
+ QMap< int, RenderTableCell* > cellsWithRowSpanZero;
+ bool containsSpansZero;
+
signed short cRow;
ushort cCol;
bool needCellRecalc;