[PATCH] tables with underspecified percents and cellspacing

Dirk Mueller mueller at kde.org
Wed Oct 23 11:16:46 BST 2002


Hi, 

this is a two in one: 

- percent tables where total sum < 100 where completely fucked. 
  see #43751, but this testcase makes it more obvious: 

<table>
     <tr>
        <td nowrap width="1%" valign="top" bgcolor="b6cbeb">#</td>
        <td nowrap width="7%" bgcolor="b6cbeb">#</td>
        <td nowrap width="7%" bgcolor="b6cbeb">#</td>
</table>

- table layout with cellspacing was completely broken. cellspacing
  was taken in account for total table width, which shouldn't be the case. 
  also the width distribution was kinda screwed. 

testcase: 

    <table cellspacing=5>
      <tr>
        <td nowrap width="1%" valign="top" align="center" 
bgcolor="b6cbeb">#</td>

        <td nowrap bgcolor="b6cbeb">#</td> 
        <td nowrap width="7%" bgcolor="b6cbeb">#</td>
   <tr>
         <td colspan=2 bgcolor=b6cbeb>#</td>
        <td nowrap width="7%" bgcolor="b6cbeb">#</td>
    </table>


below is the patch. please review/test. 



-- 
Dirk (received 210 mails today)
-------------- next part --------------
Index: render_table.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_table.cpp,v
retrieving revision 1.207
diff -u -3 -d -p -r1.207 render_table.cpp
--- render_table.cpp	2002/10/19 14:00:24	1.207
+++ render_table.cpp	2002/10/23 10:06:37
@@ -866,7 +866,7 @@ void RenderTableSection::setCellWidths()
 #ifdef DEBUG_LAYOUT
             kdDebug( 6040 ) << "lastcell: " << lastCell << " lastCol: " << lastCol << endl;
 #endif
-	    int w = columnPos[cols]-columnPos[lastCol] - table()->cellSpacing();
+	    int w = columnPos[cols]-columnPos[lastCol];
 	    int oldWidth = lastCell->width();
 #ifdef DEBUG_LAYOUT
 	    kdDebug( 6040 ) << "setting width of cell " << lastCell->row() << "/" << lastCell->col() << " to " << w << endl;
@@ -1149,7 +1149,6 @@ void RenderTableSection::print( QPainter
 
 void RenderTableSection::recalcCells()
 {
-     qDebug("recalcCells, %p",  this);
     cCol = cRow = 0;
     clearGrid();
     grid.resize( 0 );
Index: render_table.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_table.h,v
retrieving revision 1.77
diff -u -3 -d -p -r1.77 render_table.h
--- render_table.h	2002/09/24 16:05:34	1.77
+++ render_table.h	2002/10/23 10:06:38
@@ -27,6 +27,7 @@
 #ifndef RENDER_TABLE_H
 #define RENDER_TABLE_H
 
+#include <kglobal.h>
 #include <qcolor.h>
 #include <qptrvector.h>
 
@@ -149,7 +150,7 @@ public:
     }
 
     int bordersAndSpacing() const {
-	return borderLeft() + borderRight() + cellSpacing();
+	return borderLeft() + borderRight() + kMax(0, numEffCols()-1) * cellSpacing();
     }
 
     RenderTableCol *colElement( int col );
Index: table_layout.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/table_layout.cpp,v
retrieving revision 1.19
diff -u -3 -d -p -r1.19 table_layout.cpp
--- table_layout.cpp	2002/10/19 14:00:24	1.19
+++ table_layout.cpp	2002/10/23 10:06:40
@@ -247,13 +247,12 @@ void FixedTableLayout::calcMinMaxWidth()
     // width is fixed. If table width is percent, we set maxWidth to
     // unlimited.
 
-
+    int bs = table->bordersAndSpacing();
     table->m_minWidth = 0;
     table->m_maxWidth = 0;
-    short tableWidth = table->style()->width().type == Fixed ? table->style()->width().value - table->borderLeft() - table->borderRight() - table->cellSpacing() : 0;
+    short tableWidth = table->style()->width().type == Fixed ? table->style()->width().value - bs : 0;
 
     table->m_minWidth = calcWidthArray( tableWidth );
-    int bs = table->bordersAndSpacing();
     table->m_minWidth += bs;
 
     table->m_minWidth = kMax( table->m_minWidth, tableWidth );
@@ -277,7 +276,7 @@ void FixedTableLayout::layout()
     qDebug("FixedTableLayout::layout:");
 #endif
 
-    int w = table->width() - table->borderLeft() - table->borderRight() - table->cellSpacing();
+    int w = table->width() - table->bordersAndSpacing();
     // we know the table width by now.
     int rest = w - calcWidthArray( w );
 
@@ -361,8 +360,6 @@ void AutoTableLayout::recalcColumn( int 
     RenderTableCell *fixedContributor = 0;
     RenderTableCell *maxContributor = 0;
 
-    int spacing = table->cellSpacing();
-
     while ( child ) {
 	if ( child->isTableSection() ) {
 	    RenderTableSection *section = static_cast<RenderTableSection *>(child);
@@ -374,9 +371,9 @@ void AutoTableLayout::recalcColumn( int 
 		    if ( !cell->minMaxKnown() )
 			cell->calcMinMaxWidth();
 		    if ( cell->minWidth() > l.minWidth )
-			l.minWidth = cell->minWidth() + spacing;
+			l.minWidth = cell->minWidth();
 		    if ( cell->maxWidth() > l.maxWidth ) {
-			l.maxWidth = cell->maxWidth() + spacing;
+			l.maxWidth = cell->maxWidth();
 			maxContributor = cell;
 		    }
 
@@ -508,7 +505,6 @@ void AutoTableLayout::calcMinMaxWidth()
     fullRecalc();
 
     int spanMaxWidth = calcEffectiveWidth();
-
     int minWidth = 0;
     int maxWidth = 0;
     int maxPercent = 0;
@@ -518,7 +514,7 @@ void AutoTableLayout::calcMinMaxWidth()
 	minWidth += layoutStruct[i].effMinWidth;
 	maxWidth += layoutStruct[i].effMaxWidth;
 	if ( layoutStruct[i].effWidth.type == Percent ) {
-	    int pw = (layoutStruct[i].effMaxWidth * 100 + 50) / layoutStruct[i].effWidth.value;
+	    int pw = ( layoutStruct[i].effMaxWidth * 100) / layoutStruct[i].effWidth.value;
 	    maxPercent = kMax( pw,  maxPercent );
 	} else {
 	    maxNonPercent += layoutStruct[i].effMaxWidth;
@@ -755,7 +751,6 @@ void AutoTableLayout::insertSpanCell( Re
 void AutoTableLayout::layout()
 {
     // table layout based on the values collected in the layout structure.
-
     int tableWidth = table->width() - table->bordersAndSpacing();
     int available = tableWidth;
     int nEffCols = table->numEffCols();
@@ -901,6 +896,26 @@ void AutoTableLayout::layout()
     qDebug("variable satisfied: available is %d",  available );
 #endif
 
+    // spread over percent colums
+    if ( available > 0 && hasPercent && totalPercent < 100) {
+        // still have some width to spread, distribute weighted to percent columns
+        for ( int i = 0; i < nEffCols; i++ ) {
+            Length &width = layoutStruct[i].effWidth;
+            if ( width.isPercent() ) {
+                int w = available * width.value / totalPercent;
+                available -= w;
+                totalPercent -= width.value;
+                layoutStruct[i].calcWidth += w;
+                if (!available || !totalPercent) break;
+            }
+        }
+    }
+
+#ifdef DEBUG_LAYOUT
+    qDebug("after percent distribution: available=%d",  available );
+#endif
+
+
     // spread over fixed colums
     if ( available > 0 && numFixed) {
         // still have some width to spread, distribute to fixed columns
@@ -960,9 +975,9 @@ void AutoTableLayout::layout()
 	qDebug("col %d: %d (width %d)", i, pos, layoutStruct[i].calcWidth );
 #endif
 	table->columnPos[i] = pos;
-	pos += layoutStruct[i].calcWidth;
+	pos += layoutStruct[i].calcWidth + table->cellSpacing();
     }
-    table->columnPos[table->columnPos.size()-1] = pos;
+    table->columnPos[table->columnPos.size()-1] = pos - table->cellSpacing();
 
 }
 


More information about the kfm-devel mailing list