[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

hyatt hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 07:20:15 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit be02abb20a1f719505eb8a656a00ddf985d62312
Author: hyatt <hyatt at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Jan 17 22:42:07 2003 +0000

    	The new table code from Lars.  Also includes bug fixes for
    	percentage height children in table cells, for positioning
    	of tables, and for width distribution of percentage width
    	cells.
    
            Reviewed by darin
    
            * ForwardingHeaders/rendering/table_layout.h: Added.
            * WebCore.pbproj/project.pbxproj:
            * khtml/css/cssparser.cpp:
            (StyleBaseImpl::parseValue):
            * khtml/css/cssstyleselector.cpp:
            * khtml/css/cssvalues.c:
            (findValue):
            * khtml/css/cssvalues.h:
            * khtml/css/cssvalues.in:
            * khtml/css/html4.css:
            * khtml/dom/html_table.cpp:
            (HTMLTableElement::insertRow):
            (HTMLTableElement::deleteRow):
            (HTMLTableRowElement::insertCell):
            (HTMLTableRowElement::deleteCell):
            (HTMLTableSectionElement::insertRow):
            (HTMLTableSectionElement::deleteRow):
            * khtml/html/html_tableimpl.cpp:
            (HTMLTableElementImpl::HTMLTableElementImpl):
            (HTMLTableElementImpl::setTFoot):
            (HTMLTableElementImpl::setTBody):
            (HTMLTableElementImpl::createTHead):
            (HTMLTableElementImpl::createTFoot):
            (HTMLTableElementImpl::insertRow):
            (HTMLTableElementImpl::deleteRow):
            (HTMLTableElementImpl::addChild):
            (HTMLTableElementImpl::parseAttribute):
            (HTMLTableElementImpl::attach):
            (HTMLTablePartElementImpl::parseAttribute):
            (HTMLTableSectionElementImpl::HTMLTableSectionElementImpl):
            (HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl):
            (HTMLTableSectionElementImpl::insertRow):
            (HTMLTableSectionElementImpl::deleteRow):
            (HTMLTableSectionElementImpl::numRows):
            (HTMLTableRowElementImpl::rowIndex):
            (HTMLTableRowElementImpl::insertCell):
            (HTMLTableRowElementImpl::deleteCell):
            (HTMLTableCellElementImpl::HTMLTableCellElementImpl):
            (HTMLTableCellElementImpl::parseAttribute):
            (HTMLTableCellElementImpl::attach):
            (HTMLTableColElementImpl::HTMLTableColElementImpl):
            (HTMLTableColElementImpl::parseAttribute):
            * khtml/html/html_tableimpl.h:
            * khtml/html/htmlparser.cpp:
            (KHTMLParser::insertNode):
            (KHTMLParser::getElement):
            * khtml/rendering/bidi.cpp:
            (RenderFlow::layoutInlineChildren):
            * khtml/rendering/render_body.cpp:
            (RenderBody::availableHeight):
            * khtml/rendering/render_body.h:
            * khtml/rendering/render_box.cpp:
            (RenderBox::contentWidth):
            (RenderBox::contentHeight):
            (RenderBox::calcReplacedWidth):
            (RenderBox::calcReplacedHeight):
            (RenderBox::availableHeight):
            (RenderBox::calcAbsoluteVertical):
            * khtml/rendering/render_box.h:
            * khtml/rendering/render_flow.cpp:
            (RenderFlow::layoutBlockChildren):
            (RenderFlow::leftOffset):
            (RenderFlow::rightOffset):
            (RenderFlow::addOverHangingFloats):
            (RenderFlow::calcBlockMinMaxWidth):
            (RenderFlow::calcMinMaxWidth):
            * khtml/rendering/render_form.cpp:
            * khtml/rendering/render_form.h:
            * khtml/rendering/render_frames.cpp:
            * khtml/rendering/render_frames.h:
            * khtml/rendering/render_object.cpp:
            (RenderObject::createObject):
            (RenderObject::paddingTop):
            (RenderObject::paddingBottom):
            (RenderObject::paddingLeft):
            (RenderObject::paddingRight):
            * khtml/rendering/render_object.h:
            * khtml/rendering/render_replaced.cpp:
            (RenderReplaced::calcMinMaxWidth):
            * khtml/rendering/render_root.cpp:
            (RenderRoot::RenderRoot):
            (RenderRoot::layout):
            (RenderRoot::paintObject):
            * khtml/rendering/render_root.h:
            * khtml/rendering/render_style.cpp:
            (StyleSurroundData::StyleSurroundData):
            * khtml/rendering/render_style.h:
            * khtml/rendering/render_table.cpp:
            (RenderTable::RenderTable):
            (RenderTable::~RenderTable):
            (RenderTable::setStyle):
            (RenderTable::position):
            (RenderTable::addChild):
            (RenderTable::calcWidth):
            (RenderTable::layout):
            (RenderTable::setCellWidths):
            (RenderTable::paint):
            (RenderTable::calcMinMaxWidth):
            (RenderTable::splitColumn):
            (RenderTable::appendColumn):
            (RenderTable::colElement):
            (RenderTable::recalcSections):
            (RenderTable::removeChildNode):
            (RenderTable::dump):
            (RenderTableSection::RenderTableSection):
            (RenderTableSection::~RenderTableSection):
            (RenderTableSection::detach):
            (RenderTableSection::setStyle):
            (RenderTableSection::addChild):
            (RenderTableSection::ensureRows):
            (RenderTableSection::addCell):
            (RenderTableSection::setCellWidths):
            (RenderTableSection::calcRowHeight):
            (RenderTableSection::layoutRows):
            (RenderTableSection::paint):
            (RenderTableSection::recalcCells):
            (RenderTableSection::clearGrid):
            (RenderTableSection::removeChildNode):
            (RenderTableSection::dump):
            (RenderTableRow::RenderTableRow):
            (RenderTableRow::detach):
            (RenderTableRow::setStyle):
            (RenderTableRow::addChild):
            (RenderTableRow::removeChildNode):
            (RenderTableRow::dump):
            (RenderTableRow::layout):
            (RenderTableCell::RenderTableCell):
            (RenderTableCell::detach):
            (RenderTableCell::updateFromElement):
            (RenderTableCell::getCellPercentageHeight):
            (RenderTableCell::setCellPercentageHeight):
            (RenderTableCell::calcMinMaxWidth):
            (RenderTableCell::baselinePosition):
            (RenderTableCell::setStyle):
            (RenderTableCell::paint):
            (RenderTableCell::paintBoxDecorations):
            (RenderTableCell::dump):
            (RenderTableCol::RenderTableCol):
            (RenderTableCol::updateFromElement):
            (RenderTableCol::addChild):
            (RenderTableCol::dump):
            * khtml/rendering/render_table.h:
            * khtml/rendering/table_layout.cpp: Added.
            (FixedTableLayout::FixedTableLayout):
            (FixedTableLayout::~FixedTableLayout):
            (FixedTableLayout::calcWidthArray):
            (FixedTableLayout::calcMinMaxWidth):
            (FixedTableLayout::layout):
            (AutoTableLayout::AutoTableLayout):
            (AutoTableLayout::~AutoTableLayout):
            (AutoTableLayout::recalcColumn):
            (AutoTableLayout::fullRecalc):
            (AutoTableLayout::calcMinMaxWidth):
            (AutoTableLayout::calcEffectiveWidth):
            (AutoTableLayout::insertSpanCell):
            (AutoTableLayout::layout):
            (AutoTableLayout::calcPercentages):
            * khtml/rendering/table_layout.h: Added.
            * khtml/xml/dom_docimpl.cpp:
            (DocumentImpl::createHTMLElement):
            * khtml/xml/dom_nodeimpl.cpp:
            (NodeImpl::NodeImpl):
            (NodeImpl::dump):
            * khtml/xml/dom_nodeimpl.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3351 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2003-10-25 b/WebCore/ChangeLog-2003-10-25
index 6fbbeac..65a01c2 100644
--- a/WebCore/ChangeLog-2003-10-25
+++ b/WebCore/ChangeLog-2003-10-25
@@ -1,3 +1,177 @@
+2003-01-17  David Hyatt  <hyatt at apple.com>
+
+	The new table code from Lars.  Also includes bug fixes for
+	percentage height children in table cells, for positioning
+	of tables, and for width distribution of percentage width
+	cells.
+	
+        Reviewed by darin
+
+        * ForwardingHeaders/rendering/table_layout.h: Added.
+        * WebCore.pbproj/project.pbxproj:
+        * khtml/css/cssparser.cpp:
+        (StyleBaseImpl::parseValue):
+        * khtml/css/cssstyleselector.cpp:
+        * khtml/css/cssvalues.c:
+        (findValue):
+        * khtml/css/cssvalues.h:
+        * khtml/css/cssvalues.in:
+        * khtml/css/html4.css:
+        * khtml/dom/html_table.cpp:
+        (HTMLTableElement::insertRow):
+        (HTMLTableElement::deleteRow):
+        (HTMLTableRowElement::insertCell):
+        (HTMLTableRowElement::deleteCell):
+        (HTMLTableSectionElement::insertRow):
+        (HTMLTableSectionElement::deleteRow):
+        * khtml/html/html_tableimpl.cpp:
+        (HTMLTableElementImpl::HTMLTableElementImpl):
+        (HTMLTableElementImpl::setTFoot):
+        (HTMLTableElementImpl::setTBody):
+        (HTMLTableElementImpl::createTHead):
+        (HTMLTableElementImpl::createTFoot):
+        (HTMLTableElementImpl::insertRow):
+        (HTMLTableElementImpl::deleteRow):
+        (HTMLTableElementImpl::addChild):
+        (HTMLTableElementImpl::parseAttribute):
+        (HTMLTableElementImpl::attach):
+        (HTMLTablePartElementImpl::parseAttribute):
+        (HTMLTableSectionElementImpl::HTMLTableSectionElementImpl):
+        (HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl):
+        (HTMLTableSectionElementImpl::insertRow):
+        (HTMLTableSectionElementImpl::deleteRow):
+        (HTMLTableSectionElementImpl::numRows):
+        (HTMLTableRowElementImpl::rowIndex):
+        (HTMLTableRowElementImpl::insertCell):
+        (HTMLTableRowElementImpl::deleteCell):
+        (HTMLTableCellElementImpl::HTMLTableCellElementImpl):
+        (HTMLTableCellElementImpl::parseAttribute):
+        (HTMLTableCellElementImpl::attach):
+        (HTMLTableColElementImpl::HTMLTableColElementImpl):
+        (HTMLTableColElementImpl::parseAttribute):
+        * khtml/html/html_tableimpl.h:
+        * khtml/html/htmlparser.cpp:
+        (KHTMLParser::insertNode):
+        (KHTMLParser::getElement):
+        * khtml/rendering/bidi.cpp:
+        (RenderFlow::layoutInlineChildren):
+        * khtml/rendering/render_body.cpp:
+        (RenderBody::availableHeight):
+        * khtml/rendering/render_body.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::contentWidth):
+        (RenderBox::contentHeight):
+        (RenderBox::calcReplacedWidth):
+        (RenderBox::calcReplacedHeight):
+        (RenderBox::availableHeight):
+        (RenderBox::calcAbsoluteVertical):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::layoutBlockChildren):
+        (RenderFlow::leftOffset):
+        (RenderFlow::rightOffset):
+        (RenderFlow::addOverHangingFloats):
+        (RenderFlow::calcBlockMinMaxWidth):
+        (RenderFlow::calcMinMaxWidth):
+        * khtml/rendering/render_form.cpp:
+        * khtml/rendering/render_form.h:
+        * khtml/rendering/render_frames.cpp:
+        * khtml/rendering/render_frames.h:
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::createObject):
+        (RenderObject::paddingTop):
+        (RenderObject::paddingBottom):
+        (RenderObject::paddingLeft):
+        (RenderObject::paddingRight):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_replaced.cpp:
+        (RenderReplaced::calcMinMaxWidth):
+        * khtml/rendering/render_root.cpp:
+        (RenderRoot::RenderRoot):
+        (RenderRoot::layout):
+        (RenderRoot::paintObject):
+        * khtml/rendering/render_root.h:
+        * khtml/rendering/render_style.cpp:
+        (StyleSurroundData::StyleSurroundData):
+        * khtml/rendering/render_style.h:
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::RenderTable):
+        (RenderTable::~RenderTable):
+        (RenderTable::setStyle):
+        (RenderTable::position):
+        (RenderTable::addChild):
+        (RenderTable::calcWidth):
+        (RenderTable::layout):
+        (RenderTable::setCellWidths):
+        (RenderTable::paint):
+        (RenderTable::calcMinMaxWidth):
+        (RenderTable::splitColumn):
+        (RenderTable::appendColumn):
+        (RenderTable::colElement):
+        (RenderTable::recalcSections):
+        (RenderTable::removeChildNode):
+        (RenderTable::dump):
+        (RenderTableSection::RenderTableSection):
+        (RenderTableSection::~RenderTableSection):
+        (RenderTableSection::detach):
+        (RenderTableSection::setStyle):
+        (RenderTableSection::addChild):
+        (RenderTableSection::ensureRows):
+        (RenderTableSection::addCell):
+        (RenderTableSection::setCellWidths):
+        (RenderTableSection::calcRowHeight):
+        (RenderTableSection::layoutRows):
+        (RenderTableSection::paint):
+        (RenderTableSection::recalcCells):
+        (RenderTableSection::clearGrid):
+        (RenderTableSection::removeChildNode):
+        (RenderTableSection::dump):
+        (RenderTableRow::RenderTableRow):
+        (RenderTableRow::detach):
+        (RenderTableRow::setStyle):
+        (RenderTableRow::addChild):
+        (RenderTableRow::removeChildNode):
+        (RenderTableRow::dump):
+        (RenderTableRow::layout):
+        (RenderTableCell::RenderTableCell):
+        (RenderTableCell::detach):
+        (RenderTableCell::updateFromElement):
+        (RenderTableCell::getCellPercentageHeight):
+        (RenderTableCell::setCellPercentageHeight):
+        (RenderTableCell::calcMinMaxWidth):
+        (RenderTableCell::baselinePosition):
+        (RenderTableCell::setStyle):
+        (RenderTableCell::paint):
+        (RenderTableCell::paintBoxDecorations):
+        (RenderTableCell::dump):
+        (RenderTableCol::RenderTableCol):
+        (RenderTableCol::updateFromElement):
+        (RenderTableCol::addChild):
+        (RenderTableCol::dump):
+        * khtml/rendering/render_table.h:
+        * khtml/rendering/table_layout.cpp: Added.
+        (FixedTableLayout::FixedTableLayout):
+        (FixedTableLayout::~FixedTableLayout):
+        (FixedTableLayout::calcWidthArray):
+        (FixedTableLayout::calcMinMaxWidth):
+        (FixedTableLayout::layout):
+        (AutoTableLayout::AutoTableLayout):
+        (AutoTableLayout::~AutoTableLayout):
+        (AutoTableLayout::recalcColumn):
+        (AutoTableLayout::fullRecalc):
+        (AutoTableLayout::calcMinMaxWidth):
+        (AutoTableLayout::calcEffectiveWidth):
+        (AutoTableLayout::insertSpanCell):
+        (AutoTableLayout::layout):
+        (AutoTableLayout::calcPercentages):
+        * khtml/rendering/table_layout.h: Added.
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::createHTMLElement):
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeImpl::NodeImpl):
+        (NodeImpl::dump):
+        * khtml/xml/dom_nodeimpl.h:
+
 2003-01-17  Darin Adler  <darin at apple.com>
 
         Reviewed by Dave.
diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 6fbbeac..65a01c2 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,177 @@
+2003-01-17  David Hyatt  <hyatt at apple.com>
+
+	The new table code from Lars.  Also includes bug fixes for
+	percentage height children in table cells, for positioning
+	of tables, and for width distribution of percentage width
+	cells.
+	
+        Reviewed by darin
+
+        * ForwardingHeaders/rendering/table_layout.h: Added.
+        * WebCore.pbproj/project.pbxproj:
+        * khtml/css/cssparser.cpp:
+        (StyleBaseImpl::parseValue):
+        * khtml/css/cssstyleselector.cpp:
+        * khtml/css/cssvalues.c:
+        (findValue):
+        * khtml/css/cssvalues.h:
+        * khtml/css/cssvalues.in:
+        * khtml/css/html4.css:
+        * khtml/dom/html_table.cpp:
+        (HTMLTableElement::insertRow):
+        (HTMLTableElement::deleteRow):
+        (HTMLTableRowElement::insertCell):
+        (HTMLTableRowElement::deleteCell):
+        (HTMLTableSectionElement::insertRow):
+        (HTMLTableSectionElement::deleteRow):
+        * khtml/html/html_tableimpl.cpp:
+        (HTMLTableElementImpl::HTMLTableElementImpl):
+        (HTMLTableElementImpl::setTFoot):
+        (HTMLTableElementImpl::setTBody):
+        (HTMLTableElementImpl::createTHead):
+        (HTMLTableElementImpl::createTFoot):
+        (HTMLTableElementImpl::insertRow):
+        (HTMLTableElementImpl::deleteRow):
+        (HTMLTableElementImpl::addChild):
+        (HTMLTableElementImpl::parseAttribute):
+        (HTMLTableElementImpl::attach):
+        (HTMLTablePartElementImpl::parseAttribute):
+        (HTMLTableSectionElementImpl::HTMLTableSectionElementImpl):
+        (HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl):
+        (HTMLTableSectionElementImpl::insertRow):
+        (HTMLTableSectionElementImpl::deleteRow):
+        (HTMLTableSectionElementImpl::numRows):
+        (HTMLTableRowElementImpl::rowIndex):
+        (HTMLTableRowElementImpl::insertCell):
+        (HTMLTableRowElementImpl::deleteCell):
+        (HTMLTableCellElementImpl::HTMLTableCellElementImpl):
+        (HTMLTableCellElementImpl::parseAttribute):
+        (HTMLTableCellElementImpl::attach):
+        (HTMLTableColElementImpl::HTMLTableColElementImpl):
+        (HTMLTableColElementImpl::parseAttribute):
+        * khtml/html/html_tableimpl.h:
+        * khtml/html/htmlparser.cpp:
+        (KHTMLParser::insertNode):
+        (KHTMLParser::getElement):
+        * khtml/rendering/bidi.cpp:
+        (RenderFlow::layoutInlineChildren):
+        * khtml/rendering/render_body.cpp:
+        (RenderBody::availableHeight):
+        * khtml/rendering/render_body.h:
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::contentWidth):
+        (RenderBox::contentHeight):
+        (RenderBox::calcReplacedWidth):
+        (RenderBox::calcReplacedHeight):
+        (RenderBox::availableHeight):
+        (RenderBox::calcAbsoluteVertical):
+        * khtml/rendering/render_box.h:
+        * khtml/rendering/render_flow.cpp:
+        (RenderFlow::layoutBlockChildren):
+        (RenderFlow::leftOffset):
+        (RenderFlow::rightOffset):
+        (RenderFlow::addOverHangingFloats):
+        (RenderFlow::calcBlockMinMaxWidth):
+        (RenderFlow::calcMinMaxWidth):
+        * khtml/rendering/render_form.cpp:
+        * khtml/rendering/render_form.h:
+        * khtml/rendering/render_frames.cpp:
+        * khtml/rendering/render_frames.h:
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::createObject):
+        (RenderObject::paddingTop):
+        (RenderObject::paddingBottom):
+        (RenderObject::paddingLeft):
+        (RenderObject::paddingRight):
+        * khtml/rendering/render_object.h:
+        * khtml/rendering/render_replaced.cpp:
+        (RenderReplaced::calcMinMaxWidth):
+        * khtml/rendering/render_root.cpp:
+        (RenderRoot::RenderRoot):
+        (RenderRoot::layout):
+        (RenderRoot::paintObject):
+        * khtml/rendering/render_root.h:
+        * khtml/rendering/render_style.cpp:
+        (StyleSurroundData::StyleSurroundData):
+        * khtml/rendering/render_style.h:
+        * khtml/rendering/render_table.cpp:
+        (RenderTable::RenderTable):
+        (RenderTable::~RenderTable):
+        (RenderTable::setStyle):
+        (RenderTable::position):
+        (RenderTable::addChild):
+        (RenderTable::calcWidth):
+        (RenderTable::layout):
+        (RenderTable::setCellWidths):
+        (RenderTable::paint):
+        (RenderTable::calcMinMaxWidth):
+        (RenderTable::splitColumn):
+        (RenderTable::appendColumn):
+        (RenderTable::colElement):
+        (RenderTable::recalcSections):
+        (RenderTable::removeChildNode):
+        (RenderTable::dump):
+        (RenderTableSection::RenderTableSection):
+        (RenderTableSection::~RenderTableSection):
+        (RenderTableSection::detach):
+        (RenderTableSection::setStyle):
+        (RenderTableSection::addChild):
+        (RenderTableSection::ensureRows):
+        (RenderTableSection::addCell):
+        (RenderTableSection::setCellWidths):
+        (RenderTableSection::calcRowHeight):
+        (RenderTableSection::layoutRows):
+        (RenderTableSection::paint):
+        (RenderTableSection::recalcCells):
+        (RenderTableSection::clearGrid):
+        (RenderTableSection::removeChildNode):
+        (RenderTableSection::dump):
+        (RenderTableRow::RenderTableRow):
+        (RenderTableRow::detach):
+        (RenderTableRow::setStyle):
+        (RenderTableRow::addChild):
+        (RenderTableRow::removeChildNode):
+        (RenderTableRow::dump):
+        (RenderTableRow::layout):
+        (RenderTableCell::RenderTableCell):
+        (RenderTableCell::detach):
+        (RenderTableCell::updateFromElement):
+        (RenderTableCell::getCellPercentageHeight):
+        (RenderTableCell::setCellPercentageHeight):
+        (RenderTableCell::calcMinMaxWidth):
+        (RenderTableCell::baselinePosition):
+        (RenderTableCell::setStyle):
+        (RenderTableCell::paint):
+        (RenderTableCell::paintBoxDecorations):
+        (RenderTableCell::dump):
+        (RenderTableCol::RenderTableCol):
+        (RenderTableCol::updateFromElement):
+        (RenderTableCol::addChild):
+        (RenderTableCol::dump):
+        * khtml/rendering/render_table.h:
+        * khtml/rendering/table_layout.cpp: Added.
+        (FixedTableLayout::FixedTableLayout):
+        (FixedTableLayout::~FixedTableLayout):
+        (FixedTableLayout::calcWidthArray):
+        (FixedTableLayout::calcMinMaxWidth):
+        (FixedTableLayout::layout):
+        (AutoTableLayout::AutoTableLayout):
+        (AutoTableLayout::~AutoTableLayout):
+        (AutoTableLayout::recalcColumn):
+        (AutoTableLayout::fullRecalc):
+        (AutoTableLayout::calcMinMaxWidth):
+        (AutoTableLayout::calcEffectiveWidth):
+        (AutoTableLayout::insertSpanCell):
+        (AutoTableLayout::layout):
+        (AutoTableLayout::calcPercentages):
+        * khtml/rendering/table_layout.h: Added.
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::createHTMLElement):
+        * khtml/xml/dom_nodeimpl.cpp:
+        (NodeImpl::NodeImpl):
+        (NodeImpl::dump):
+        * khtml/xml/dom_nodeimpl.h:
+
 2003-01-17  Darin Adler  <darin at apple.com>
 
         Reviewed by Dave.
diff --git a/WebCore/ForwardingHeaders/rendering/table_layout.h b/WebCore/ForwardingHeaders/rendering/table_layout.h
new file mode 100644
index 0000000..9e6dd74
--- /dev/null
+++ b/WebCore/ForwardingHeaders/rendering/table_layout.h
@@ -0,0 +1 @@
+#include <table_layout.h>
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index 2c5bd35..6149695 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -175,6 +175,7 @@
 </dict>
 </plist>
 ";
+			shouldUseHeadermap = 0;
 		};
 		0867D69DFE84028FC02AAC07 = {
 			buildActionMask = 2147483647;
@@ -478,6 +479,7 @@
 				93F12CB103CCFD570000011C,
 				93F12CB303CCFD570000011C,
 				93F12CC803CD0AE60000011C,
+				BCF0192703D3802200B2D04D,
 				931BFCD003D4AEDA008635CE,
 				931BFCD403D4AEE5008635CE,
 				931BFCD803D4AEFD008635CE,
@@ -718,6 +720,7 @@
 				93F12CAD03CCFD570000011C,
 				93F12CAE03CCFD570000011C,
 				93F12CB003CCFD570000011C,
+				BCF0192603D3802200B2D04D,
 				931BFCD103D4AEDA008635CE,
 				931BFCD503D4AEE5008635CE,
 				931BFCD903D4AEFD008635CE,
@@ -1456,6 +1459,30 @@
 			settings = {
 			};
 		};
+		BCF0192403D3802200B2D04D = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			path = table_layout.cpp;
+			refType = 4;
+		};
+		BCF0192503D3802200B2D04D = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			path = table_layout.h;
+			refType = 4;
+		};
+		BCF0192603D3802200B2D04D = {
+			fileRef = BCF0192403D3802200B2D04D;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		BCF0192703D3802200B2D04D = {
+			fileRef = BCF0192503D3802200B2D04D;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 //BC0
 //BC1
 //BC2
@@ -4168,6 +4195,10 @@
 				F523D2C402DE4438018635CA,
 				F523D2C702DE4438018635CA,
 				F523D2C602DE4438018635CA,
+				BC7294FB03804B5600A80166,
+				BC7294FC03804B5600A80166,
+				BCF0192403D3802200B2D04D,
+				BCF0192503D3802200B2D04D,
 			);
 			isa = PBXGroup;
 			path = rendering;
diff --git a/WebCore/khtml/css/cssparser.cpp b/WebCore/khtml/css/cssparser.cpp
index 229168d..7aeaa75 100644
--- a/WebCore/khtml/css/cssparser.cpp
+++ b/WebCore/khtml/css/cssparser.cpp
@@ -1198,7 +1198,7 @@ bool StyleBaseImpl::parseValue( const QChar *curP, const QChar *endP, int propId
 	//    [<color> || <length> <length> <length>?] | inherit
 
       case CSS_PROP_UNICODE_BIDI:         // normal | embed | bidi-override | inherit
-      case CSS_PROP_WHITE_SPACE:          // normal | pre | nowrap | inherit
+      case CSS_PROP_WHITE_SPACE:          // normal | pre | nowrap | -konq-nowrap | inherit
       case CSS_PROP_FONT_STRETCH:
         // normal | wider | narrower | ultra-condensed | extra-condensed | condensed |
         // semi-condensed |  semi-expanded | expanded | extra-expanded | ultra-expanded |
diff --git a/WebCore/khtml/css/cssstyleselector.cpp b/WebCore/khtml/css/cssstyleselector.cpp
index f832c82..c36a6f8 100644
--- a/WebCore/khtml/css/cssstyleselector.cpp
+++ b/WebCore/khtml/css/cssstyleselector.cpp
@@ -1743,6 +1743,9 @@ void CSSStyleSelector::applyRule( DOM::CSSProperty *prop )
 
         EWhiteSpace s;
         switch(primitiveValue->getIdent()) {
+        case CSS_VAL__KONQ_NOWRAP:
+            s = KONQ_NOWRAP;
+            break;
         case CSS_VAL_NOWRAP:
             s = NOWRAP;
             break;
diff --git a/WebCore/khtml/css/cssvalues.c b/WebCore/khtml/css/cssvalues.c
index f329941..f73ef92 100644
--- a/WebCore/khtml/css/cssvalues.c
+++ b/WebCore/khtml/css/cssvalues.c
@@ -108,7 +108,7 @@ findValue (register const char *str, register unsigned int len)
 {
   enum
     {
-      TOTAL_KEYWORDS = 180,
+      TOTAL_KEYWORDS = 181,
       MIN_WORD_LENGTH = 3,
       MAX_WORD_LENGTH = 21,
       MIN_HASH_VALUE = 0,
@@ -280,6 +280,7 @@ findValue (register const char *str, register unsigned int len)
       {"medium", CSS_VAL_MEDIUM},
       {"higher", CSS_VAL_HIGHER},
       {"table-column", CSS_VAL_TABLE_COLUMN},
+      {"-konq-nowrap", CSS_VAL__KONQ_NOWRAP},
       {"message-box", CSS_VAL_MESSAGE_BOX},
       {"ultra-condensed", CSS_VAL_ULTRA_CONDENSED},
       {"-konq-normal", CSS_VAL__KONQ_NORMAL},
@@ -316,7 +317,7 @@ findValue (register const char *str, register unsigned int len)
         -1,   -1,   17,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   18,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   19,
-      -302, -160,   -2,   22,   -1,   -1,   -1,   -1,
+      -303, -161,   -2,   22,   -1,   -1,   -1,   -1,
         -1,   -1,   23,   -1,   -1,   24,   -1,   -1,
         -1,   -1,   -1,   -1,   25,   -1,   -1,   26,
         27,   -1,   -1,   -1,   -1,   -1,   28,   -1,
@@ -392,32 +393,33 @@ findValue (register const char *str, register unsigned int len)
         -1,  161,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,  162,   -1,   -1,   -1,   -1,   -1,
+        -1,  163,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  164,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  163,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  165,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  164,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  166,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  165,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,  167,   -1,   -1,
+        -1,   -1,   -1,   -1,  168,   -1,   -1,   -1,
+        -1,  169,   -1,   -1,   -1,   -1,   -1,  170,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  166,   -1,   -1,
-        -1,   -1,   -1,   -1,  167,   -1,   -1,   -1,
-        -1,  168,   -1,   -1,   -1,   -1,   -1,  169,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  171,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  170,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,   -1,  172,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,  171,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -425,22 +427,21 @@ findValue (register const char *str, register unsigned int len)
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  172,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,  173,   -1,   -1,   -1,
+        -1,   -1,   -1,   -1,  174,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,  174,   -1,
+        -1,   -1,   -1,   -1,   -1,   -1,  175,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  175,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  176,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,  176,   -1,   -1,   -1,   -1,   -1,
-       177,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+        -1,   -1,  177,   -1,   -1,   -1,   -1,   -1,
+       178,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -457,7 +458,7 @@ findValue (register const char *str, register unsigned int len)
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  178,   -1,   -1,   -1,   -1,
+        -1,   -1,   -1,  179,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -473,7 +474,7 @@ findValue (register const char *str, register unsigned int len)
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  179
+        -1,   -1,   -1,   -1,   -1,  180
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
@@ -690,6 +691,7 @@ static const char * const valueList[] = {
 "thick", 
 "thin", 
 "underline", 
+"-konq-nowrap", 
 "-konq-normal", 
 "-konq-around-floats", 
     0
diff --git a/WebCore/khtml/css/cssvalues.h b/WebCore/khtml/css/cssvalues.h
index 8084801..9f1691c 100644
--- a/WebCore/khtml/css/cssvalues.h
+++ b/WebCore/khtml/css/cssvalues.h
@@ -187,9 +187,10 @@ DOM::DOMString getValueName(unsigned short id);
 #define CSS_VAL_THICK 176
 #define CSS_VAL_THIN 177
 #define CSS_VAL_UNDERLINE 178
-#define CSS_VAL__KONQ_NORMAL 179
-#define CSS_VAL__KONQ_AROUND_FLOATS 180
+#define CSS_VAL__KONQ_NOWRAP 179
+#define CSS_VAL__KONQ_NORMAL 180
+#define CSS_VAL__KONQ_AROUND_FLOATS 181
 
-#define CSS_VAL_TOTAL 181
+#define CSS_VAL_TOTAL 182
 #endif
 
diff --git a/WebCore/khtml/css/cssvalues.in b/WebCore/khtml/css/cssvalues.in
index f59ff2b..c457364 100644
--- a/WebCore/khtml/css/cssvalues.in
+++ b/WebCore/khtml/css/cssvalues.in
@@ -258,6 +258,7 @@ static-position
 thick
 thin
 underline
+-konq-nowrap
 # CSS_PROP__KONQ_FLOW_MODE
 -konq-normal
 -konq-around-floats
diff --git a/WebCore/khtml/css/html4.css b/WebCore/khtml/css/html4.css
index 6fe608d..343d6c4 100644
--- a/WebCore/khtml/css/html4.css
+++ b/WebCore/khtml/css/html4.css
@@ -187,8 +187,7 @@ TABLE {
 	text-align: -konq-auto;
 	border-spacing: 2px;
 	border-color: gray;
-	padding: 1px;
-        -konq-flow-mode: -konq-around-floats;
+    -konq-flow-mode: -konq-around-floats;
 }
 
 TD[align=left] > TABLE {
@@ -207,19 +206,19 @@ TABLE[align="center"] {
 THEAD { 
 	display: table-header-group; 
     vertical-align: middle;
-	border: inherit;
+    border-color: inherit;
 }
       
 TBODY { 
 	display: table-row-group;
     vertical-align: middle; 
-    border: inherit;
+    border-color: inherit;
 }
       
 TFOOT { 
 	display: table-footer-group; 
     vertical-align: middle;
-	border: inherit; 
+    border-color: inherit;
 }
 
 COL { 
diff --git a/WebCore/khtml/dom/html_table.cpp b/WebCore/khtml/dom/html_table.cpp
index 746fd2a..8c981a9 100644
--- a/WebCore/khtml/dom/html_table.cpp
+++ b/WebCore/khtml/dom/html_table.cpp
@@ -606,13 +606,20 @@ void HTMLTableElement::deleteCaption(  )
 HTMLElement HTMLTableElement::insertRow( long index )
 {
     if(!impl) return 0;
-    return ((HTMLTableElementImpl *)impl)->insertRow( index );
+    int exceptioncode = 0;
+    HTMLElementImpl* ret = ((HTMLTableElementImpl *)impl)->insertRow( index, exceptioncode );
+    if (exceptioncode)
+        throw DOMException(exceptioncode);
+    return ret;
 }
 
 void HTMLTableElement::deleteRow( long index )
 {
+    int exceptioncode = 0;
     if(impl)
-        ((HTMLTableElementImpl *)impl)->deleteRow( index );
+        ((HTMLTableElementImpl *)impl)->deleteRow( index, exceptioncode );
+    if (exceptioncode)
+        throw DOMException(exceptioncode);
 }
 
 // --------------------------------------------------------------------------
@@ -736,13 +743,20 @@ void HTMLTableRowElement::setVAlign( const DOMString &value )
 HTMLElement HTMLTableRowElement::insertCell( long index )
 {
     if(!impl) return 0;
-    return ((HTMLTableRowElementImpl *)impl)->insertCell( index );
+    int exceptioncode = 0;
+    HTMLElementImpl* ret = ((HTMLTableRowElementImpl *)impl)->insertCell( index, exceptioncode );
+    if (exceptioncode)
+        throw DOMException(exceptioncode);
+    return ret;
 }
 
 void HTMLTableRowElement::deleteCell( long index )
 {
+    int exceptioncode = 0;
     if(impl)
-        ((HTMLTableRowElementImpl *)impl)->deleteCell( index );
+        ((HTMLTableRowElementImpl *)impl)->deleteCell( index, exceptioncode );
+    if (exceptioncode)
+        throw DOMException(exceptioncode);
 }
 
 // --------------------------------------------------------------------------
@@ -836,12 +850,19 @@ HTMLCollection HTMLTableSectionElement::rows() const
 HTMLElement HTMLTableSectionElement::insertRow( long index )
 {
     if(!impl) return 0;
-    return ((HTMLTableSectionElementImpl *)impl)->insertRow( index );
+    int exceptioncode = 0;
+    HTMLElementImpl* ret = ((HTMLTableSectionElementImpl *)impl)->insertRow( index, exceptioncode );
+    if (exceptioncode)
+        throw DOMException(exceptioncode);
+    return ret;
 }
 
 void HTMLTableSectionElement::deleteRow( long index )
 {
+    int exceptioncode = 0;
     if(impl)
-        ((HTMLTableSectionElementImpl *)impl)->deleteRow( index );
+        ((HTMLTableSectionElementImpl *)impl)->deleteRow( index, exceptioncode );
+    if (exceptioncode)
+        throw DOMException(exceptioncode);
 }
 
diff --git a/WebCore/khtml/html/html_tableimpl.cpp b/WebCore/khtml/html/html_tableimpl.cpp
index fa6e3d9..a38cbf8 100644
--- a/WebCore/khtml/html/html_tableimpl.cpp
+++ b/WebCore/khtml/html/html_tableimpl.cpp
@@ -42,6 +42,7 @@
 #include "rendering/render_table.h"
 
 #include <kdebug.h>
+#include <kglobal.h>
 
 using namespace khtml;
 using namespace DOM;
@@ -54,12 +55,12 @@ HTMLTableElementImpl::HTMLTableElementImpl(DocumentPtr *doc)
     foot = 0;
     firstBody = 0;
 
+#if 0
     rules = None;
     frame = Void;
-
-    m_cellPadding = -1;
+#endif
+    padding = 1;
     
-    incremental = false;
     m_noBorder = true;
     m_solid = false;
 }
@@ -73,28 +74,6 @@ NodeImpl::Id HTMLTableElementImpl::id() const
     return ID_TABLE;
 }
 
-void HTMLTableElementImpl::attach()
-{
-    assert(!m_attached);
-    if (parent()->renderer()) {
-        // reset font color and sizes here, if we don't have strict parse mode.
-        // this is 90% compatible to ie and mozilla, and the by way easiest solution...
-        // only difference to 100% correct is that in strict mode <font> elements are propagated into tables.
-        if ( getDocument()->parseMode() != DocumentImpl::Strict ) {
-            addCSSProperty( CSS_PROP_FONT_SIZE, CSS_VAL_MEDIUM );
-            addCSSProperty( CSS_PROP_COLOR, getDocument()->textColor() );
-            addCSSProperty( CSS_PROP_FONT_FAMILY, "konq_body" );
-        }
-    }
-
-    HTMLElementImpl::attach();
-    
-    if (m_render && m_render->isTable()) {
-        RenderTable* table = static_cast<RenderTable*>(m_render);
-        table->setCellPadding(m_cellPadding);
-    }
-}
-
 NodeImpl* HTMLTableElementImpl::setCaption( HTMLTableCaptionElementImpl *c )
 {
     int exceptioncode = 0;
@@ -135,8 +114,7 @@ NodeImpl* HTMLTableElementImpl::setTFoot( HTMLTableSectionElementImpl *s )
     if(foot) {
         replaceChild ( s, foot, exceptioncode );
         r = s;
-    }
-    else if( firstBody )
+    } else if( firstBody )
         r = insertBefore( s, firstBody, exceptioncode );
     else
         r = appendChild( s, exceptioncode );
@@ -149,13 +127,12 @@ NodeImpl* HTMLTableElementImpl::setTBody( HTMLTableSectionElementImpl *s )
     int exceptioncode = 0;
     NodeImpl* r;
 
-    if(!firstBody)
-        firstBody = s;
-
-    if( foot )
-        r = insertBefore( s, foot, exceptioncode );
-    else
+    if(firstBody) {
+        replaceChild ( s, firstBody, exceptioncode );
+        r = s;
+    } else
         r = appendChild( s, exceptioncode );
+    firstBody = s;
 
     return r;
 }
@@ -165,10 +142,10 @@ HTMLElementImpl *HTMLTableElementImpl::createTHead(  )
     if(!head)
     {
         int exceptioncode = 0;
-        head = new HTMLTableSectionElementImpl(docPtr(), ID_THEAD);
+        head = new HTMLTableSectionElementImpl(docPtr(), ID_THEAD, true /* implicit */);
         if(foot)
             insertBefore( head, foot, exceptioncode );
-        if(firstBody)
+        else if(firstBody)
             insertBefore( head, firstBody, exceptioncode);
         else
             appendChild(head, exceptioncode);
@@ -190,7 +167,7 @@ HTMLElementImpl *HTMLTableElementImpl::createTFoot(  )
     if(!foot)
     {
         int exceptioncode = 0;
-        foot = new HTMLTableSectionElementImpl(docPtr(), ID_TFOOT);
+        foot = new HTMLTableSectionElementImpl(docPtr(), ID_TFOOT, true /*implicit */);
         if(firstBody)
             insertBefore( foot, firstBody, exceptioncode );
         else
@@ -228,48 +205,98 @@ void HTMLTableElementImpl::deleteCaption(  )
     tCaption = 0;
 }
 
-HTMLElementImpl *HTMLTableElementImpl::insertRow( long index )
+HTMLElementImpl *HTMLTableElementImpl::insertRow( long index, int &exceptioncode )
 {
+    // The DOM requires that we create a tbody if the table is empty
+    // (cf DOM2TS HTMLTableElement31 test)
+    // (note: this is different from "if the table has no sections", since we can have
+    // <TABLE><TR>)
+    if(!firstBody && !head && !foot && !hasChildNodes())
+        setTBody( new HTMLTableSectionElementImpl(docPtr(), ID_TBODY, true /* implicit */) );
+
+    //kdDebug(6030) << k_funcinfo << index << endl;
     // IE treats index=-1 as default value meaning 'append after last'
     // This isn't in the DOM. So, not implemented yet.
     HTMLTableSectionElementImpl* section = 0L;
+    HTMLTableSectionElementImpl* lastSection = 0L;
     NodeImpl *node = firstChild();
-    for ( ; node ; node = node->nextSibling() )
+    bool append = (index == -1);
+    bool found = false;
+    for ( ; node && (index>=0 || append) ; node = node->nextSibling() )
     {
-        if ( node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY )
+	// there could be 2 tfoot elements in the table. Only the first one is the "foot", that's why we have the more
+	// complicated if statement below.
+        if ( node != foot && (node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY) )
         {
             section = static_cast<HTMLTableSectionElementImpl *>(node);
-            if ( section->numRows() > index )
-                break;
-            else
-                index -= section->numRows();
+            lastSection = section;
+            //kdDebug(6030) << k_funcinfo << "section id=" << node->id() << " rows:" << section->numRows() << endl;
+            if ( !append )
+            {
+                int rows = section->numRows();
+                if ( rows > index ) {
+		    found = true;
+                    break;
+                } else
+                    index -= rows;
+                //kdDebug(6030) << "       index is now " << index << endl;
+            }
         }
     }
-    if (!section) {
-        section = new HTMLTableSectionElementImpl(docPtr(), ID_TBODY);
-        setTBody( section );
+    if ( !found && foot )
+        section = static_cast<HTMLTableSectionElementImpl *>(foot);
+
+    // Index == 0 means "insert before first row in current section"
+    // or "append after last row" (if there's no current section anymore)
+    if ( !section && ( index == 0 || append ) )
+    {
+        section = lastSection;
+        index = section ? section->numRows() : 0;
+    }
+    if ( section && (index >= 0 || append) ) {
+        //kdDebug(6030) << "Inserting row into section " << section << " at index " << index << endl;
+        return section->insertRow( index, exceptioncode );
+    } else {
+        // No more sections => index is too big
+        exceptioncode = DOMException::INDEX_SIZE_ERR;
+        return 0L;
     }
-    return section->insertRow( index );
 }
 
-void HTMLTableElementImpl::deleteRow( long index )
+void HTMLTableElementImpl::deleteRow( long index, int &exceptioncode )
 {
     HTMLTableSectionElementImpl* section = 0L;
     NodeImpl *node = firstChild();
+    bool lastRow = index == -1;
+    HTMLTableSectionElementImpl* lastSection = 0L;
+    bool found = false;
     for ( ; node ; node = node->nextSibling() )
     {
-        if ( node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY )
+        if ( node != foot && (node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY) )
         {
             section = static_cast<HTMLTableSectionElementImpl *>(node);
-            if ( section->numRows() > index )
-                break;
-            else
-                index -= section->numRows();
+            lastSection = section;
+            int rows = section->numRows();
+            if ( !lastRow )
+            {
+                if ( rows > index ) {
+                    found = true;
+                    break;
+                } else
+                    index -= rows;
+            }
         }
+        section = 0L;
     }
-    if ( section && index >= 0 && index < section->numRows() )
-        section->deleteRow( index );
-    // ## TODO error checking, returning exceptioncode
+    if ( !found && foot )
+        section = static_cast<HTMLTableSectionElementImpl *>(foot);
+
+    if ( lastRow )
+        lastSection->deleteRow( -1, exceptioncode );
+    else if ( section && index >= 0 && index < section->numRows() )
+        section->deleteRow( index, exceptioncode );
+    else
+        exceptioncode = DOMException::INDEX_SIZE_ERR;
 }
 
 NodeImpl *HTMLTableElementImpl::addChild(NodeImpl *child)
@@ -278,41 +305,40 @@ NodeImpl *HTMLTableElementImpl::addChild(NodeImpl *child)
     kdDebug( 6030 ) << nodeName().string() << "(Table)::addChild( " << child->nodeName().string() << " )" << endl;
 #endif
 
-    switch(child->id())
-    {
-    case ID_CAPTION:
-        return setCaption(static_cast<HTMLTableCaptionElementImpl *>(child));
-        break;
-    case ID_COL:
-    case ID_COLGROUP:
-        {
-        // these have to come before the table definition!
-        if(head || foot || firstBody)
-            return 0;
-        HTMLElementImpl::addChild(child);
-        // ###
-        }
-        return child;
-    case ID_THEAD:
-        //      if(incremental && !columnPos[totalCols]);// calcColWidth();
-        return setTHead(static_cast<HTMLTableSectionElementImpl *>(child));
-        break;
-    case ID_TFOOT:
-        //if(incremental && !columnPos[totalCols]);// calcColWidth();
-        return setTFoot(static_cast<HTMLTableSectionElementImpl *>(child));
-        break;
-    case ID_TBODY:
-        //if(incremental && !columnPos[totalCols]);// calcColWidth();
-        return setTBody(static_cast<HTMLTableSectionElementImpl *>(child));
-        break;
-    case ID_FORM:
+    if (child->id() == ID_FORM) {
         // First add the child.
         HTMLElementImpl::addChild(child);
         // Now simply return ourselves as the newnode.  This has the effect of
         // demoting the form to a leaf and moving it safely out of the way.
         return this;
     }
-    return 0;
+    
+    int exceptioncode = 0;
+    NodeImpl *retval = appendChild( child, exceptioncode );
+    if ( retval ) {
+	switch(child->id()) {
+	case ID_CAPTION:
+	    if ( !tCaption )
+		tCaption = static_cast<HTMLTableCaptionElementImpl *>(child);
+	    break;
+	case ID_COL:
+	case ID_COLGROUP:
+	    break;
+	case ID_THEAD:
+	    if ( !head )
+		head = static_cast<HTMLTableSectionElementImpl *>(child);
+	    break;
+	case ID_TFOOT:
+	    if ( !foot )
+		foot = static_cast<HTMLTableSectionElementImpl *>(child);
+	    break;
+	case ID_TBODY:
+	    if ( !firstBody )
+		firstBody = static_cast<HTMLTableSectionElementImpl *>(child);
+	    break;
+	}
+    }
+    return retval;
 }
 
 void HTMLTableElementImpl::parseAttribute(AttributeImpl *attr)
@@ -322,7 +348,7 @@ void HTMLTableElementImpl::parseAttribute(AttributeImpl *attr)
     {
     case ATTR_WIDTH:
         if (!attr->value().isEmpty())
-            addCSSLength(CSS_PROP_WIDTH, attr->value());
+            addCSSLength( CSS_PROP_WIDTH, attr->value() );
         else
             removeCSSProperty(CSS_PROP_WIDTH);
         break;
@@ -429,13 +455,9 @@ void HTMLTableElementImpl::parseAttribute(AttributeImpl *attr)
         break;
     case ATTR_CELLPADDING:
         if (!attr->value().isEmpty())
-            m_cellPadding = attr->value().toInt();
-        else 
-            m_cellPadding = -1;
-        if (m_render && m_render->isTable()) {
-            RenderTable* table = static_cast<RenderTable*>(m_render);
-            table->setCellPadding(m_cellPadding);
-        }
+            padding = kMax( 0, attr->value().toInt() );
+        else
+            padding = 0;
         break;
     case ATTR_COLS:
     {
@@ -466,17 +488,31 @@ void HTMLTableElementImpl::parseAttribute(AttributeImpl *attr)
     }
 }
 
-void HTMLTableElementImpl::init()
+void HTMLTableElementImpl::attach()
 {
-    HTMLElementImpl::init();
-
-    if (!m_noBorder) {
-        int v = m_solid ? CSS_VAL_SOLID : CSS_VAL_OUTSET;
-        addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, v);
-        addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v);
-        addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, v);
-        addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, v);
+    assert(!m_attached);
+    if (parent()->renderer()) {
+        // reset font color and sizes here, if we don't have strict parse mode.
+        // this is 90% compatible to ie and mozilla, and the by way easiest solution...
+        // only difference to 100% correct is that in strict mode <font> elements are propagated into tables.
+        if ( getDocument()->parseMode() != DocumentImpl::Strict ) {
+            addCSSProperty( CSS_PROP_FONT_SIZE, CSS_VAL_MEDIUM );
+            addCSSProperty( CSS_PROP_COLOR, getDocument()->textColor() );
+            addCSSProperty( CSS_PROP_FONT_FAMILY, "konq_body" );
+        }
+        
+        if (!m_noBorder) {
+            int v = m_solid ? CSS_VAL_SOLID : CSS_VAL_OUTSET;
+            addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, v);
+            addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v);
+            addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, v);
+            addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, v);
+        }
     }
+
+    HTMLElementImpl::attach();
+    if ( m_render && m_render->isTable() )
+	static_cast<RenderTable *>(m_render)->setCellPadding( padding );
 }
 
 // --------------------------------------------------------------------------
@@ -510,7 +546,6 @@ void HTMLTablePartElementImpl::parseAttribute(AttributeImpl *attr)
             addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID);
             addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
             addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
-            m_solid = true;
         }
         break;
     }
@@ -530,6 +565,12 @@ void HTMLTablePartElementImpl::parseAttribute(AttributeImpl *attr)
         addCSSProperty(CSS_PROP_TEXT_ALIGN, v);
         break;
     }
+    case ATTR_HEIGHT:
+        if (!attr->value().isEmpty())
+            addCSSLength(CSS_PROP_HEIGHT, attr->value());
+        else
+            removeCSSProperty(CSS_PROP_HEIGHT);
+        break;
     case ATTR_NOSAVE:
 	break;
     default:
@@ -540,15 +581,15 @@ void HTMLTablePartElementImpl::parseAttribute(AttributeImpl *attr)
 // -------------------------------------------------------------------------
 
 HTMLTableSectionElementImpl::HTMLTableSectionElementImpl(DocumentPtr *doc,
-                                                         ushort tagid)
+                                                         ushort tagid, bool implicit)
     : HTMLTablePartElementImpl(doc)
 {
     _id = tagid;
+    m_implicit = implicit;
 }
 
 HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl()
 {
-    nrows = 0;
 }
 
 NodeImpl::Id HTMLTableSectionElementImpl::id() const
@@ -574,52 +615,61 @@ NodeImpl *HTMLTableSectionElementImpl::addChild(NodeImpl *child)
 
 // these functions are rather slow, since we need to get the row at
 // the index... but they aren't used during usual HTML parsing anyway
-HTMLElementImpl *HTMLTableSectionElementImpl::insertRow( long index )
+HTMLElementImpl *HTMLTableSectionElementImpl::insertRow( long index, int& exceptioncode )
 {
-    nrows++;
-
-    HTMLTableRowElementImpl *r = new HTMLTableRowElementImpl(docPtr());
-
+    HTMLTableRowElementImpl *r = 0L;
     NodeListImpl *children = childNodes();
-    int exceptioncode = 0;
-    if(!children || (int)children->length() <= index)
-        appendChild(r, exceptioncode);
-    else {
-        NodeImpl *n;
-        if(index < 1)
-            n = firstChild();
-        else
-            n = children->item(index);
-        insertBefore(r, n, exceptioncode );
+    int numRows = children ? (int)children->length() : 0;
+    //kdDebug(6030) << k_funcinfo << "index=" << index << " numRows=" << numRows << endl;
+    if ( index < -1 || index > numRows ) {
+        exceptioncode = DOMException::INDEX_SIZE_ERR; // per the DOM
+    }
+    else
+    {
+        r = new HTMLTableRowElementImpl(docPtr());
+        if ( numRows == index || index == -1 )
+            appendChild(r, exceptioncode);
+        else {
+            NodeImpl *n;
+            if(index < 1)
+                n = firstChild();
+            else
+                n = children->item(index);
+            insertBefore(r, n, exceptioncode );
+        }
     }
-    if(children) delete children;
+    delete children;
     return r;
 }
 
-void HTMLTableSectionElementImpl::deleteRow( long index )
+void HTMLTableSectionElementImpl::deleteRow( long index, int &exceptioncode )
 {
-    if(index < 0) return;
     NodeListImpl *children = childNodes();
-    if(children && (int)children->length() > index)
-    {
-        nrows--;
-        int exceptioncode = 0;
+    int numRows = children ? (int)children->length() : 0;
+    if ( index == -1 ) index = numRows - 1;
+    if( index >= 0 && index < numRows )
         HTMLElementImpl::removeChild(children->item(index), exceptioncode);
-    }
-    if(children) delete children;
+    else
+        exceptioncode = DOMException::INDEX_SIZE_ERR;
+    delete children;
 }
 
-// -------------------------------------------------------------------------
 
-HTMLTableRowElementImpl::HTMLTableRowElementImpl(DocumentPtr *doc)
-  : HTMLTablePartElementImpl(doc)
+int HTMLTableSectionElementImpl::numRows() const
 {
-}
+    int rows = 0;
+    const NodeImpl *n = firstChild();
+    while (n) {
+        if (n->id() == ID_TR)
+            rows++;
+        n = n->nextSibling();
+    }
 
-HTMLTableRowElementImpl::~HTMLTableRowElementImpl()
-{
+    return rows;
 }
 
+// -------------------------------------------------------------------------
+
 NodeImpl::Id HTMLTableRowElementImpl::id() const
 {
     return ID_TR;
@@ -643,26 +693,39 @@ NodeImpl *HTMLTableRowElementImpl::addChild(NodeImpl *child)
 
 long HTMLTableRowElementImpl::rowIndex() const
 {
-    // some complex traversal stuff here to take into account that some rows may be in different sections
     int rIndex = 0;
-    const NodeImpl *n = this;
-    do {
-        while (!n->previousSibling() && !(n->isElementNode() && n->id() == ID_TABLE))
-            n = n->parentNode();
-        if (n->isElementNode() && n->id() == ID_TABLE)
-            n = 0;
-        if (n) {
-            n = n->previousSibling();
-            while (!(n->isElementNode() && n->id() == ID_TR) && n->lastChild())
-                n = n->lastChild();
-        }
-
-        if (n && n->isElementNode() && n->id() == ID_TR)
-            rIndex++;
-    }
-    while (n && n->isElementNode() && n->id() == ID_TR);
 
-    return rIndex;
+    NodeImpl *table = parentNode();
+    if ( !table )
+	return -1;
+    table = table->parentNode();
+    if ( !table || table->id() != ID_TABLE )
+	return -1;
+
+    HTMLTableSectionElementImpl *foot = static_cast<HTMLTableElementImpl *>(table)->tFoot();
+    NodeImpl *node = table->firstChild();
+    while ( node ) {
+        if ( node != foot && (node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY) ) {
+	    HTMLTableSectionElementImpl* section = static_cast<HTMLTableSectionElementImpl *>(node);
+	    const NodeImpl *row = section->firstChild();
+	    while ( row ) {
+		if ( row == this )
+		    return rIndex;
+		rIndex++;
+		row = row->nextSibling();
+	    }
+	}
+	node = node->nextSibling();
+    }
+    const NodeImpl *row = foot->firstChild();
+    while ( row ) {
+	if ( row == this )
+	    return rIndex;
+	rIndex++;
+	row = row->nextSibling();
+    }
+    // should never happen
+    return -1;
 }
 
 long HTMLTableRowElementImpl::sectionRowIndex() const
@@ -679,35 +742,41 @@ long HTMLTableRowElementImpl::sectionRowIndex() const
     return rIndex;
 }
 
-HTMLElementImpl *HTMLTableRowElementImpl::insertCell( long index )
+HTMLElementImpl *HTMLTableRowElementImpl::insertCell( long index, int &exceptioncode )
 {
-    HTMLTableCellElementImpl *c = new HTMLTableCellElementImpl(docPtr(), ID_TD);
-
+    HTMLTableCellElementImpl *c = 0L;
     NodeListImpl *children = childNodes();
-    int exceptioncode = 0;
-    if(!children || (int)children->length() <= index)
-        appendChild(c, exceptioncode);
-    else {
-        NodeImpl *n;
-        if(index < 1)
-            n = firstChild();
-        else
-            n = children->item(index);
-        insertBefore(c, n, exceptioncode);
+    int numCells = children ? children->length() : 0;
+    if ( index < -1 || index > numCells )
+        exceptioncode = DOMException::INDEX_SIZE_ERR; // per the DOM
+    else
+    {
+        c = new HTMLTableCellElementImpl(docPtr(), ID_TD);
+        if(numCells == index || index == -1)
+            appendChild(c, exceptioncode);
+        else {
+            NodeImpl *n;
+            if(index < 1)
+                n = firstChild();
+            else
+                n = children->item(index);
+            insertBefore(c, n, exceptioncode);
+        }
     }
-    if(children) delete children;
+    delete children;
     return c;
 }
 
-void HTMLTableRowElementImpl::deleteCell( long index )
+void HTMLTableRowElementImpl::deleteCell( long index, int &exceptioncode )
 {
-    if(index < 0) return;
     NodeListImpl *children = childNodes();
-    if(children && (int)children->length() > index) {
-        int exceptioncode = 0;
+    int numCells = children ? children->length() : 0;
+    if ( index == -1 ) index = numCells-1;
+    if( index >= 0 && index < numCells )
         HTMLElementImpl::removeChild(children->item(index), exceptioncode);
-    }
-    if(children) delete children;
+    else
+        exceptioncode = DOMException::INDEX_SIZE_ERR;
+    delete children;
 }
 
 // -------------------------------------------------------------------------
@@ -718,9 +787,9 @@ HTMLTableCellElementImpl::HTMLTableCellElementImpl(DocumentPtr *doc, int tag)
   _col = -1;
   _row = -1;
   cSpan = rSpan = 1;
-  m_nowrap = false;
   _id = tag;
   rowHeight = 0;
+  m_solid = false;
 }
 
 HTMLTableCellElementImpl::~HTMLTableCellElementImpl()
@@ -748,20 +817,17 @@ void HTMLTableCellElementImpl::parseAttribute(AttributeImpl *attr)
         if(cSpan < 1 || cSpan > 1024) cSpan = 1;
         break;
     case ATTR_NOWRAP:
-        m_nowrap = (attr->val() != 0);
+        if (attr->val() != 0)
+            addCSSProperty(CSS_PROP_WHITE_SPACE, "-konq-nowrap");
+        else
+            removeCSSProperty(CSS_PROP_WHITE_SPACE);
         break;
     case ATTR_WIDTH:
         if (!attr->value().isEmpty())
-            addCSSLength(CSS_PROP_WIDTH, attr->value());
+            addCSSLength( CSS_PROP_WIDTH, attr->value() );
         else
             removeCSSProperty(CSS_PROP_WIDTH);
         break;
-    case ATTR_HEIGHT:
-        if (!attr->value().isEmpty())
-            addCSSLength(CSS_PROP_HEIGHT, attr->value());
-        else
-            removeCSSProperty(CSS_PROP_HEIGHT);
-        break;
     case ATTR_NOSAVE:
 	break;
     default:
@@ -769,10 +835,8 @@ void HTMLTableCellElementImpl::parseAttribute(AttributeImpl *attr)
     }
 }
 
-void HTMLTableCellElementImpl::init()
+void HTMLTableCellElementImpl::attach()
 {
-    HTMLTablePartElementImpl::init();
-
     HTMLElementImpl* p = static_cast<HTMLElementImpl*>(parentNode());
     while(p && p->id() != ID_TABLE)
         p = static_cast<HTMLElementImpl*>(p->parentNode());
@@ -794,50 +858,25 @@ void HTMLTableCellElementImpl::init()
                 addCSSProperty(CSS_PROP_BORDER_COLOR, "inherit");
         }
     }
+
+    HTMLTablePartElementImpl::attach();
 }
 
 // -------------------------------------------------------------------------
 
 HTMLTableColElementImpl::HTMLTableColElementImpl(DocumentPtr *doc, ushort i)
-    : HTMLElementImpl(doc)
+    : HTMLTablePartElementImpl(doc)
 {
     _id = i;
     _span = (_id == ID_COLGROUP ? 0 : 1);
 }
 
-HTMLTableColElementImpl::~HTMLTableColElementImpl()
-{
-}
-
 NodeImpl::Id HTMLTableColElementImpl::id() const
 {
     return _id;
 }
 
 
-NodeImpl *HTMLTableColElementImpl::addChild(NodeImpl *child)
-{
-#ifdef DEBUG_LAYOUT
-    kdDebug( 6030 ) << nodeName().string() << "(Table)::addChild( " << child->nodeName().string() << " )" << endl;
-#endif
-
-    switch(child->id())
-    {
-    case ID_COL:
-    {
-        // these have to come before the table definition!
-        HTMLElementImpl::addChild(child);
-        return child;
-    }
-    default:
-        return 0;
-        break;
-        // ####
-    }
-    return child;
-
-}
-
 void HTMLTableColElementImpl::parseAttribute(AttributeImpl *attr)
 {
     switch(attr->id())
@@ -858,22 +897,13 @@ void HTMLTableColElementImpl::parseAttribute(AttributeImpl *attr)
             removeCSSProperty(CSS_PROP_VERTICAL_ALIGN);
         break;
     default:
-        HTMLElementImpl::parseAttribute(attr);
+        HTMLTablePartElementImpl::parseAttribute(attr);
     }
 
 }
 
 // -------------------------------------------------------------------------
 
-HTMLTableCaptionElementImpl::HTMLTableCaptionElementImpl(DocumentPtr *doc)
-  : HTMLTablePartElementImpl(doc)
-{
-}
-
-HTMLTableCaptionElementImpl::~HTMLTableCaptionElementImpl()
-{
-}
-
 NodeImpl::Id HTMLTableCaptionElementImpl::id() const
 {
     return ID_CAPTION;
diff --git a/WebCore/khtml/html/html_tableimpl.h b/WebCore/khtml/html/html_tableimpl.h
index 849ab44..d3d23ae 100644
--- a/WebCore/khtml/html/html_tableimpl.h
+++ b/WebCore/khtml/html/html_tableimpl.h
@@ -74,8 +74,6 @@ public:
 
     virtual Id id() const;
 
-    virtual void attach();
-    
     HTMLTableCaptionElementImpl *caption() const { return tCaption; }
     NodeImpl *setCaption( HTMLTableCaptionElementImpl * );
 
@@ -93,31 +91,29 @@ public:
     void deleteTFoot (  );
     HTMLElementImpl *createCaption (  );
     void deleteCaption (  );
-    HTMLElementImpl *insertRow ( long index );
-    void deleteRow ( long index );
+    HTMLElementImpl *insertRow ( long index, int &exceptioncode );
+    void deleteRow ( long index, int &exceptioncode );
 
     // overrides
     virtual NodeImpl *addChild(NodeImpl *child);
     virtual void parseAttribute(AttributeImpl *attr);
+    virtual void attach();
 
-    virtual void init();
-
-    int cellPadding() { return m_cellPadding; }
-    
 protected:
     HTMLTableSectionElementImpl *head;
     HTMLTableSectionElementImpl *foot;
     HTMLTableSectionElementImpl *firstBody;
     HTMLTableCaptionElementImpl *tCaption;
 
+#if 0
     Frame frame;
     Rules rules;
+#endif
 
-    int m_cellPadding;
-    
-    bool incremental : 1;
-    bool m_noBorder  : 1;
-    bool m_solid     : 1;
+    bool m_noBorder     : 1;
+    bool m_solid        : 1;
+    uint unused		: 14;
+    ushort padding	: 16;
     friend class HTMLTableCellElementImpl;
 };
 
@@ -128,13 +124,10 @@ class HTMLTablePartElementImpl : public HTMLElementImpl
 {
 public:
     HTMLTablePartElementImpl(DocumentPtr *doc)
-        : HTMLElementImpl(doc), m_solid(false)
+        : HTMLElementImpl(doc)
         { }
 
     virtual void parseAttribute(AttributeImpl *attr);
-
-protected:
-    bool m_solid : 1;
 };
 
 // -------------------------------------------------------------------------
@@ -142,7 +135,7 @@ protected:
 class HTMLTableSectionElementImpl : public HTMLTablePartElementImpl
 {
 public:
-    HTMLTableSectionElementImpl(DocumentPtr *doc, ushort tagid);
+    HTMLTableSectionElementImpl(DocumentPtr *doc, ushort tagid, bool implicit);
 
     ~HTMLTableSectionElementImpl();
 
@@ -150,14 +143,13 @@ public:
 
     virtual NodeImpl *addChild(NodeImpl *child);
     
-    HTMLElementImpl *insertRow ( long index );
-    void deleteRow ( long index );
+    HTMLElementImpl *insertRow ( long index, int& exceptioncode );
+    void deleteRow ( long index, int& exceptioncode );
 
-    int numRows() const { return nrows; }
+    int numRows() const;
 
 protected:
     ushort _id;
-    int nrows;
 };
 
 // -------------------------------------------------------------------------
@@ -165,9 +157,8 @@ protected:
 class HTMLTableRowElementImpl : public HTMLTablePartElementImpl
 {
 public:
-    HTMLTableRowElementImpl(DocumentPtr *doc);
-
-    ~HTMLTableRowElementImpl();
+    HTMLTableRowElementImpl(DocumentPtr *doc)
+        : HTMLTablePartElementImpl(doc) {}
 
     virtual Id id() const;
 
@@ -176,8 +167,8 @@ public:
     long rowIndex() const;
     long sectionRowIndex() const;
 
-    HTMLElementImpl *insertCell ( long index );
-    void deleteCell ( long index );
+    HTMLElementImpl *insertCell ( long index, int &exceptioncode );
+    void deleteCell ( long index, int &exceptioncode );
 
 protected:
     int ncols;
@@ -198,14 +189,13 @@ public:
     void setCol(int col) { _col = col; }
     int row() const { return _row; }
     void setRow(int r) { _row = r; }
-    
+
     int colSpan() const { return cSpan; }
     int rowSpan() const { return rSpan; }
-    bool noWrap() const { return m_nowrap; }
-
+    
     virtual Id id() const { return _id; }
     virtual void parseAttribute(AttributeImpl *attr);
-    virtual void init();
+    virtual void attach();
 
 protected:
     int _row;
@@ -214,28 +204,23 @@ protected:
     int cSpan;
     int _id;
     int rowHeight;
-
-    bool m_nowrap : 1;
+    bool m_solid        : 1;
 };
 
 // -------------------------------------------------------------------------
 
-class HTMLTableColElementImpl : public HTMLElementImpl
+class HTMLTableColElementImpl : public HTMLTablePartElementImpl
 {
 public:
     HTMLTableColElementImpl(DocumentPtr *doc, ushort i);
 
-    ~HTMLTableColElementImpl();
-
     virtual Id id() const;
 
     void setTable(HTMLTableElementImpl *t) { table = t; }
 
-    virtual NodeImpl *addChild(NodeImpl *child);
-
     // overrides
     virtual void parseAttribute(AttributeImpl *attr);
-    
+
     int span() const { return _span; }
 
 protected:
@@ -252,12 +237,10 @@ protected:
 class HTMLTableCaptionElementImpl : public HTMLTablePartElementImpl
 {
 public:
-    HTMLTableCaptionElementImpl(DocumentPtr *doc);
-
-    ~HTMLTableCaptionElementImpl();
+    HTMLTableCaptionElementImpl(DocumentPtr *doc)
+        : HTMLTablePartElementImpl(doc) {}
 
     virtual Id id() const;
-
     virtual void parseAttribute(AttributeImpl *attr);
 };
 
diff --git a/WebCore/khtml/html/htmlparser.cpp b/WebCore/khtml/html/htmlparser.cpp
index 2e501bc..5640548 100644
--- a/WebCore/khtml/html/htmlparser.cpp
+++ b/WebCore/khtml/html/htmlparser.cpp
@@ -667,7 +667,7 @@ bool KHTMLParser::insertNode(NodeImpl *n, bool flat)
                 if ( current->id() == ID_TR )
                     e = new HTMLTableCellElementImpl(document, ID_TD);
                 else if ( current->id() == ID_TABLE )
-                    e = new HTMLTableSectionElementImpl( document, ID_TBODY );
+                    e = new HTMLTableSectionElementImpl( document, ID_TBODY, true /* implicit */ );
                 else
                     e = new HTMLTableRowElementImpl( document );
                 
@@ -1037,7 +1037,7 @@ NodeImpl *KHTMLParser::getElement(Token* t)
         popBlock( ID_THEAD );
         popBlock( ID_TBODY );
         popBlock( ID_TFOOT );
-        n = new HTMLTableSectionElementImpl(document, t->id);
+        n = new HTMLTableSectionElementImpl(document, t->id, false);
         break;
 
 // inline elements
diff --git a/WebCore/khtml/rendering/bidi.cpp b/WebCore/khtml/rendering/bidi.cpp
index ecbdcff..a39d40f 100644
--- a/WebCore/khtml/rendering/bidi.cpp
+++ b/WebCore/khtml/rendering/bidi.cpp
@@ -1032,11 +1032,8 @@ void RenderFlow::layoutInlineChildren(bool relayoutChildren)
     int toAdd = style()->borderBottomWidth();
     m_height = style()->borderTopWidth();
 
-    if(hasPadding())
-    {
-        m_height += paddingTop();
-        toAdd += paddingBottom();
-    }
+    m_height += paddingTop();
+    toAdd += paddingBottom();
     
     if(firstChild()) {
         // layout replaced elements
diff --git a/WebCore/khtml/rendering/render_body.cpp b/WebCore/khtml/rendering/render_body.cpp
index c8f7a64..2f133a4 100644
--- a/WebCore/khtml/rendering/render_body.cpp
+++ b/WebCore/khtml/rendering/render_body.cpp
@@ -26,7 +26,7 @@
 #include "xml/dom_docimpl.h"
 #include "khtmlview.h"
 
-
+#include <kglobal.h>
 #include <kdebug.h>
 
 using namespace khtml;
@@ -102,3 +102,16 @@ void RenderBody::layout()
     }
 #endif /* APPLE_CHANGES not defined */
 }
+
+int RenderBody::availableHeight() const
+{
+    int h = RenderFlow::availableHeight();
+
+    if( style()->marginTop().isFixed() )
+        h  -= style()->marginTop().value;
+    if( style()->marginBottom().isFixed() )
+        h -= style()->marginBottom().value;
+
+    return kMax(0, h);
+}
+
diff --git a/WebCore/khtml/rendering/render_body.h b/WebCore/khtml/rendering/render_body.h
index 1740c02..ceb0a5e 100644
--- a/WebCore/khtml/rendering/render_body.h
+++ b/WebCore/khtml/rendering/render_body.h
@@ -42,11 +42,11 @@ public:
     virtual const char *renderName() const { return "RenderBody"; }
     virtual void repaint(bool immediate=false);
 
-
     virtual void layout();
-
     virtual void setStyle(RenderStyle* style);
 
+    virtual int availableHeight() const;
+    
 protected:
     virtual void paintBoxDecorations(QPainter *p,int _x, int _y,
                                      int _w, int _h, int _tx, int _ty);
diff --git a/WebCore/khtml/rendering/render_box.cpp b/WebCore/khtml/rendering/render_box.cpp
index 2592425..90cad8e 100644
--- a/WebCore/khtml/rendering/render_box.cpp
+++ b/WebCore/khtml/rendering/render_box.cpp
@@ -107,8 +107,7 @@ void RenderBox::detach(RenderArena* renderArena)
 short RenderBox::contentWidth() const
 {
     short w = m_width - borderLeft() - borderRight();
-    if (hasPadding())
-        w -= paddingLeft() + paddingRight();
+    w -= paddingLeft() + paddingRight();
 
     //kdDebug( 6040 ) << "RenderBox::contentWidth(2) = " << w << endl;
     return w;
@@ -117,8 +116,7 @@ short RenderBox::contentWidth() const
 int RenderBox::contentHeight() const
 {
     int h = m_height - borderTop() - borderBottom();
-    if (hasPadding())
-        h -= paddingTop() + paddingBottom();
+    h -= paddingTop() + paddingBottom();
 
     return h;
 }
@@ -715,108 +713,80 @@ void RenderBox::calcHeight()
     }
 }
 
-short RenderBox::calcReplacedWidth(bool* ieHack) const
+short RenderBox::calcReplacedWidth() const
 {
-    Length w = style()->width();
-    short width;
-    if ( ieHack )
-        *ieHack = style()->height().isPercent() || w.isPercent();
+   Length w = style()->width();
 
-    switch( w.type ) {
-    case Variable:
-    {
-        Length h = style()->height();
-        int ih = intrinsicHeight();
-        if ( ih > 0 && ( h.isPercent() || h.isFixed() ) )
-            width = ( ( h.isPercent() ? calcReplacedHeight() : h.value )*intrinsicWidth() ) / ih;
-        else
-            width = intrinsicWidth();
-        break;
-    }
+   switch( w.type ) {
+    case Fixed:
+        return w.value;
     case Percent:
     {
-        //RenderObject* p = parent();
-        int cw = containingBlockWidth();
-        if ( cw ) {
-            width = w.minWidth( cw );
-#if APPLE_CHANGES
-            // Aqua form controls have margins.  In order to make this work out well,
-            // subtract our margins out.
+        const int cw = containingBlockWidth();
+        if (cw > 0) {
+            int result = w.minWidth(cw);
+#ifdef APPLE_CHANGES
+            // Because we put margins on our form controls, for percentage widths, it's best to subtract
+            // them out so the controls fit snugly and don't overflow.  This is gross.  Technically we
+            // should probably stop using margins and build the spacing into the form controls ourselves, but
+            // then how would the author override? -dwh
             if (isFormElement())
-                width -= (marginLeft() + marginRight());
+                result -= (marginLeft() + marginRight());
 #endif
+            return result;
         }
-        else
-            width = intrinsicWidth();
-        break;
     }
-    case Fixed:
-        width = w.value;
-        break;
+    // fall through
     default:
-        width = intrinsicWidth();
-        break;
-    };
-
-    return width;
+        return intrinsicWidth();
+    }
 }
 
 int RenderBox::calcReplacedHeight() const
 {
-    Length h = style()->height();
-    short height;
+    const Length& h = style()->height();
     switch( h.type ) {
-    case Variable:
-    {
-        Length w = style()->width();
-        int iw = intrinsicWidth();
-        if( iw > 0 && ( w.isFixed() || w.isPercent() ))
-            height = (( w.isPercent() ? calcReplacedWidth() : w.value ) * intrinsicHeight()) / iw;
-        else
-            height = intrinsicHeight();
-    }
-    break;
-    case Percent:
-    {
-        RenderObject* p = parent();
-        while (p && !p->isTableCell()) p = p->parent();
-        bool doIEHack = !p;
-        RenderObject* cb = containingBlock();
-        if ( !cb->isTableCell() && doIEHack)
-            height = h.minWidth( cb->root()->view()->visibleHeight() );
-        else {
-	    if (cb->isTableCell()) {
-	        RenderTableCell* tableCell = static_cast<RenderTableCell*>(cb);
-	        if (tableCell->style()->height().isPercent() && tableCell->getCellPercentageHeight()) {
-                height = h.minWidth(tableCell->getCellPercentageHeight());
-#if APPLE_CHANGES
-                // Aqua form controls have margins.  In order to make this work out well,
-                // subtract our margins out.
-                if (isFormElement())
-                    height -= (marginTop() + marginBottom());
+    case Percent: {
+        int ah = availableHeight();
+#ifdef APPLE_CHANGES
+        // Because we put margins on our form controls, for percentage heights, it's best to subtract
+        // them out so the controls fit snugly and don't overflow.  This is gross.  Technically we
+        // should probably stop using margins and build the spacing into the form controls ourselves,
+        // but then how would the author override? -dwh
+        if (isFormElement())
+            ah -= (marginTop() + marginBottom());
 #endif
-                    break;
-                }
-            }
-            
-            if (!doIEHack)
-                cb = cb->containingBlock();
-            
-            if ( cb->style()->height().isFixed() )
-                height = h.minWidth( cb->style()->height().value );
-            else
-                height = intrinsicHeight();
-        }
+        return ah;
     }
-    break;
     case Fixed:
-        height = h.value;
-        break;
+        return h.value;
     default:
-        height = intrinsicHeight();
+        return intrinsicHeight();
     };
+}
+
+int RenderBox::availableHeight() const
+{
+    Length h = style()->height();
 
-    return height;
+    if (h.isFixed())
+        return h.value;
+
+    if (isRoot())
+        return static_cast<const RenderRoot*>(this)->viewportHeight();
+
+    // We need to stop here, since we don't want to increase the height of the table
+    // artificially.  We're going to rely on this cell getting expanded to some new
+    // height, and then when we lay out again we'll use the calculation below.
+    if (isTableCell() && (h.isVariable() || h.isPercent())) {
+        const RenderTableCell* tableCell = static_cast<const RenderTableCell*>(this);
+        return tableCell->getCellPercentageHeight() - (borderLeft()+borderRight()+paddingLeft()+paddingRight());
+    }
+    
+    if (h.isPercent())
+       return h.width(containingBlock()->availableHeight());
+       
+    return containingBlock()->availableHeight();
 }
 
 void RenderBox::calcVerticalMargins()
@@ -1015,6 +985,8 @@ void RenderBox::calcAbsoluteVertical()
     if (hl.isFixed())
         ch = hl.value + cb->paddingTop()
              + cb->paddingBottom();
+    else if (cb->isHtml())
+        ch = cb->availableHeight();
     else
         ch = cb->height();
 
@@ -1022,7 +994,11 @@ void RenderBox::calcAbsoluteVertical()
         t = style()->top().width(ch) + cb->borderTop();
     if(!style()->bottom().isVariable())
         b = style()->bottom().width(ch) + cb->borderBottom();
-    if(!style()->height().isVariable())
+    if (isTable() && style()->height().isVariable())
+        // Height is never unsolved for tables. "auto" means shrink to fit.  Use our
+        // height instead.
+        h = m_height - pab;
+    else if(!style()->height().isVariable())
     {
         h = style()->height().width(ch);
         
diff --git a/WebCore/khtml/rendering/render_box.h b/WebCore/khtml/rendering/render_box.h
index 1cf470a..4d427d0 100644
--- a/WebCore/khtml/rendering/render_box.h
+++ b/WebCore/khtml/rendering/render_box.h
@@ -101,9 +101,11 @@ public:
 
     int calcWidthUsing(WidthType widthType, int cw, LengthType& lengthType);
     
-    virtual short calcReplacedWidth(bool* ieHack=0) const;
+    virtual short calcReplacedWidth() const;
     virtual int   calcReplacedHeight() const;
 
+    virtual int availableHeight() const;
+    
     void calcVerticalMargins();
 
     void relativePositionOffset(int &tx, int &ty);
diff --git a/WebCore/khtml/rendering/render_flow.cpp b/WebCore/khtml/rendering/render_flow.cpp
index 927a4b4..981df84 100644
--- a/WebCore/khtml/rendering/render_flow.cpp
+++ b/WebCore/khtml/rendering/render_flow.cpp
@@ -416,19 +416,10 @@ void RenderFlow::layoutBlockChildren( bool relayoutChildren )
 
     m_height = 0;
 
-    if(style()->hasBorder())
-    {
-        xPos += borderLeft();
-        m_height += borderTop();
-        toAdd += borderBottom();
-    }
-    if (hasPadding())
-    {
-        xPos += paddingLeft();
-        m_height += paddingTop();
-        toAdd += paddingBottom();
-    }
-
+    xPos += borderLeft() + paddingLeft();
+    m_height += borderTop() + paddingTop();
+    toAdd += borderBottom() + paddingBottom();
+   
     int minHeight = m_height + toAdd;
     m_overflowHeight = m_height;
     
@@ -1003,10 +994,7 @@ RenderFlow::leftOffset() const
 {
     int left = 0;
 
-    if (style()->hasBorder())
-        left += borderLeft();
-    if (hasPadding())
-        left += paddingLeft();
+    left += borderLeft() + paddingLeft();
 
     if ( firstLine && style()->direction() == LTR ) {
         int cw=0;
@@ -1047,10 +1035,7 @@ RenderFlow::rightOffset() const
 {
     int right = m_width;
 
-    if (style()->hasBorder())
-        right -= borderRight();
-    if (hasPadding())
-        right -= paddingRight();
+    right -= borderRight() + paddingRight();
 
     if ( firstLine && style()->direction() == RTL ) {
         int cw=0;
@@ -1300,7 +1285,7 @@ void RenderFlow::addOverHangingFloats( RenderFlow *flow, int xoff, int offset, b
 #ifdef DEBUG_LAYOUT
     kdDebug( 6040 ) << (void *)this << ": adding overhanging floats xoff=" << xoff << "  offset=" << offset << " child=" << child << endl;
 #endif
-    if ( !flow->specialObjects )
+    if ( !flow->specialObjects || (child && flow->layer()) )
         return;
 
     // we have overhanging floats
@@ -1316,7 +1301,7 @@ void RenderFlow::addOverHangingFloats( RenderFlow *flow, int xoff, int offset, b
             ( ( !child && r->endY > offset ) ||
             ( child && flow->yPos() + r->endY > height() ) ) ) {
             
-            if ( child )
+            if (child)
                 r->noPaint = true;
                 
             SpecialObject* f = 0;
@@ -1619,6 +1604,8 @@ void RenderFlow::calcInlineMinMaxWidth()
 
 void RenderFlow::calcBlockMinMaxWidth()
 {
+    bool nowrap = style()->whiteSpace() == NOWRAP; 
+           
     RenderObject *child = firstChild();
     while(child != 0)
     {
@@ -1670,6 +1657,10 @@ void RenderFlow::calcBlockMinMaxWidth()
 
         int w = child->minWidth() + margin;
         if(m_minWidth < w) m_minWidth = w;
+        // IE ignores tables for calculation of nowrap. Makes some sense.
+	    if ( nowrap && !child->isTable() && m_maxWidth < w )
+            m_maxWidth = w;
+        
         w = child->maxWidth() + margin;
         if(m_maxWidth < w) m_maxWidth = w;
         child = child->nextSibling();
@@ -1693,6 +1684,7 @@ void RenderFlow::calcMinMaxWidth()
         return;
     }
 
+    bool preOrNowrap = style()->whiteSpace() != NORMAL;          
     if (childrenInline())
         calcInlineMinMaxWidth();
     else
@@ -1700,17 +1692,14 @@ void RenderFlow::calcMinMaxWidth()
         
     if(m_maxWidth < m_minWidth) m_maxWidth = m_minWidth;
 
-    if (style()->width().isFixed())
-        m_maxWidth = KMAX(m_minWidth,short(style()->width().value));
-
-    if ( style()->whiteSpace() != NORMAL )
+    if (preOrNowrap && childrenInline())
         m_minWidth = m_maxWidth;
-
+        
+    if (style()->width().isFixed() && style()->width().value > 0)
+        m_maxWidth = KMAX(m_minWidth,short(style()->width().value));
+    
     int toAdd = 0;
-    if(style()->hasBorder())
-        toAdd = borderLeft() + borderRight();
-    if (hasPadding())
-        toAdd += paddingLeft() + paddingRight();
+    toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();
 
     m_minWidth += toAdd;
     m_maxWidth += toAdd;
diff --git a/WebCore/khtml/rendering/render_form.cpp b/WebCore/khtml/rendering/render_form.cpp
index 70423a0..8516d08 100644
--- a/WebCore/khtml/rendering/render_form.cpp
+++ b/WebCore/khtml/rendering/render_form.cpp
@@ -76,24 +76,6 @@ short RenderFormElement::baselinePosition( bool f ) const
 #endif
 }
 
-short RenderFormElement::calcReplacedWidth(bool*) const
-{
-    Length w = style()->width();
-    if ( w.isVariable() )
-        return intrinsicWidth();
-    else
-        return RenderReplaced::calcReplacedWidth();
-}
-
-int RenderFormElement::calcReplacedHeight() const
-{
-    Length h = style()->height();
-    if ( h.isVariable() )
-        return intrinsicHeight();
-    else
-        return RenderReplaced::calcReplacedHeight();
-}
-
 void RenderFormElement::updateFromElement()
 {
     m_widget->setEnabled(!element()->disabled());
diff --git a/WebCore/khtml/rendering/render_form.h b/WebCore/khtml/rendering/render_form.h
index 01f1b20..ec0a48b 100644
--- a/WebCore/khtml/rendering/render_form.h
+++ b/WebCore/khtml/rendering/render_form.h
@@ -85,10 +85,6 @@ public:
     int paddingRight() const { return 0; }
 #endif
 
-    // IE does not scale according to intrinsicWidth/Height
-    // aspect ratio :-(
-    virtual short calcReplacedWidth(bool* ieHack=0) const;
-    virtual int   calcReplacedHeight() const;
     virtual void updateFromElement();
 
     virtual void layout();
diff --git a/WebCore/khtml/rendering/render_frames.cpp b/WebCore/khtml/rendering/render_frames.cpp
index cc5141d..2c68d20 100644
--- a/WebCore/khtml/rendering/render_frames.cpp
+++ b/WebCore/khtml/rendering/render_frames.cpp
@@ -913,50 +913,6 @@ void RenderPartObject::slotPartLoadingErrorNotify()
 #endif // APPLE_CHANGES
 }
 
-// duplication of RenderFormElement... FIX THIS!
-short RenderPartObject::calcReplacedWidth(bool* ieHack) const
-{
-    Length w = style()->width();
-    
-    // Always setting ieHack is incorrect and causes the following example test case to break.
-    // <table width="100%" height="90">
-    // <tr>
-    //   <td width="200" style="border: 2px solid green">
-    //     <object width="200" height="90" style="border: 2px solid red">
-    //       <embed width="200" height="90" style="border: 2px solid blue"></embed>
-    //     </object>
-    //   </td>
-    //   <td width="100%" style="border: 2px solid blue"></td>
-    //   <td width="500" style="border: 2px solid green">
-    //     <object width="500" height="90" style="border: 2px solid red">
-    //       <embed width="500" height="90" style="border: 2px solid blue"></embed>
-    //     </object>
-    //   </td>
-    // </tr>
-    // </table>
-    //
-    // Real-world example is at: http://www.moveabletype.com/top.html
-    // I am commenting this out, since it causes all plugins to have a min width of 0
-    // all the time (unless they have a variable length).  This is clearly wrong. - dwh
-    if ( w.isVariable() ) {
-        if (ieHack) // Move it inside.  Only applies in the override case. -dwh
-            *ieHack = true;
-        return intrinsicWidth();
-    }
-    else
-        return RenderReplaced::calcReplacedWidth();
-}
-
-int RenderPartObject::calcReplacedHeight() const
-{
-    Length h = style()->height();
-    if ( h.isVariable() )
-        return intrinsicHeight();
-    else
-        return RenderReplaced::calcReplacedHeight();
-}
-// end duplication
-
 void RenderPartObject::layout( )
 {
     KHTMLAssert( !layouted() );
diff --git a/WebCore/khtml/rendering/render_frames.h b/WebCore/khtml/rendering/render_frames.h
index d6faa00..739d144 100644
--- a/WebCore/khtml/rendering/render_frames.h
+++ b/WebCore/khtml/rendering/render_frames.h
@@ -146,11 +146,6 @@ public:
     virtual void layout( );
     virtual void updateWidget();
 
-    // IE does not scale according to intrinsicWidth/Height
-    // aspect ratio :-(
-    virtual short calcReplacedWidth(bool* ieHack=0) const;
-    virtual int   calcReplacedHeight() const;
-
     virtual bool partLoadingErrorNotify( khtml::ChildFrame *childFrame, const KURL& url, const QString& serviceType );
 
 public slots:
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index 8c5c9a4..86af2f8 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -108,7 +108,7 @@ RenderObject *RenderObject::createObject(DOM::NodeImpl* node,  RenderStyle* styl
         o = new (arena) RenderTableCell(node);
         break;
     case TABLE_CAPTION:
-        o = new (arena) RenderTableCaption(node);
+        o = new (arena) RenderFlow(node);
         break;
     }
     if(o) o->setStyle(style);
@@ -868,34 +868,50 @@ void RenderObject::cursorPos(int /*offset*/, int &_x, int &_y, int &height)
 
 int RenderObject::paddingTop() const
 {
-    int cw=0;
-    if (style()->paddingTop().isPercent())
-        cw = containingBlock()->contentWidth();
-    return m_style->paddingTop().minWidth(cw);
+    int w = 0;
+    Length padding = m_style->paddingTop();
+    if (padding.isPercent())
+        w = containingBlock()->contentWidth();
+    w = padding.minWidth(w);
+    if ( isTableCell() && padding.isVariable() )
+	w = static_cast<const RenderTableCell *>(this)->table()->cellPadding();
+    return w;
 }
 
 int RenderObject::paddingBottom() const
 {
-    int cw=0;
-    if (style()->paddingBottom().isPercent())
-        cw = containingBlock()->contentWidth();
-    return m_style->paddingBottom().minWidth(cw);
+    int w = 0;
+    Length padding = style()->paddingBottom();
+    if (padding.isPercent())
+        w = containingBlock()->contentWidth();
+    w = padding.minWidth(w);
+    if ( isTableCell() && padding.isVariable() )
+	w = static_cast<const RenderTableCell *>(this)->table()->cellPadding();
+    return w;
 }
 
 int RenderObject::paddingLeft() const
 {
-    int cw=0;
-    if (style()->paddingLeft().isPercent())
-        cw = containingBlock()->contentWidth();
-    return m_style->paddingLeft().minWidth(cw);
+    int w = 0;
+    Length padding = style()->paddingLeft();
+    if (padding.isPercent())
+        w = containingBlock()->contentWidth();
+    w = padding.minWidth(w);
+    if ( isTableCell() && padding.isVariable() )
+	w = static_cast<const RenderTableCell *>(this)->table()->cellPadding();
+    return w;
 }
 
 int RenderObject::paddingRight() const
 {
-    int cw=0;
-    if (style()->paddingRight().isPercent())
-        cw = containingBlock()->contentWidth();
-    return m_style->paddingRight().minWidth(cw);
+    int w = 0;
+    Length padding = style()->paddingRight();
+    if (padding.isPercent())
+        w = containingBlock()->contentWidth();
+    w = padding.minWidth(w);
+    if ( isTableCell() && padding.isVariable() )
+	w = static_cast<const RenderTableCell *>(this)->table()->cellPadding();
+    return w;
 }
 
 RenderRoot* RenderObject::root() const
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index 2751f0e..cfe912a 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -173,6 +173,7 @@ public:
     virtual bool isTableCell() const { return false; }
     virtual bool isTableRow() const { return false; }
     virtual bool isTableSection() const { return false; }
+    virtual bool isTableCol() const { return false; }
     virtual bool isTable() const { return false; }
     virtual bool isWidget() const { return false; }
     virtual bool isBody() const { return false; }
@@ -308,6 +309,8 @@ public:
     // The corresponding closing element has been parsed. ### remove me
     virtual void close() { }
 
+    virtual int availableHeight() const { return 0; }
+    
     // does a query on the rendertree and finds the innernode
     // and overURL for the given position
     // if readonly == false, it will recalc hover styles accordingly
@@ -446,7 +449,6 @@ public:
     virtual int paddingBottom() const;
     virtual int paddingLeft() const;
     virtual int paddingRight() const;
-    virtual bool hasPadding() const { return style()->hasPadding(); }
     
     virtual int borderTop() const { return style()->borderTopWidth(); }
     virtual int borderBottom() const { return style()->borderBottomWidth(); }
diff --git a/WebCore/khtml/rendering/render_replaced.cpp b/WebCore/khtml/rendering/render_replaced.cpp
index 13cb862..85c9f4d 100644
--- a/WebCore/khtml/rendering/render_replaced.cpp
+++ b/WebCore/khtml/rendering/render_replaced.cpp
@@ -82,21 +82,17 @@ void RenderReplaced::calcMinMaxWidth()
     kdDebug( 6040 ) << "RenderReplaced::calcMinMaxWidth() known=" << minMaxKnown() << endl;
 #endif
 
-    bool isPercent = false;
-    int width = calcReplacedWidth(&isPercent);
+    int width = calcReplacedWidth();
 
-    int toAdd = 0;
-    if (hasPadding())
-        toAdd += paddingLeft() + paddingRight();
-    if (style()->hasBorder())
-        toAdd += borderLeft() + borderRight();
+    if (!isWidget())
+        width += paddingLeft() + paddingRight() + borderLeft() + borderRight();
 
-    if ( isPercent ) {
+    if ( style()->width().isPercent() || style()->height().isPercent() ) {
         m_minWidth = 0;
-        m_maxWidth = width + toAdd;
+        m_maxWidth = width;
     }
     else
-        m_minWidth = m_maxWidth = width + toAdd;
+        m_minWidth = m_maxWidth = width;
 
     setMinMaxKnown();
 }
diff --git a/WebCore/khtml/rendering/render_root.cpp b/WebCore/khtml/rendering/render_root.cpp
index 93f2d02..2ebf000 100644
--- a/WebCore/khtml/rendering/render_root.cpp
+++ b/WebCore/khtml/rendering/render_root.cpp
@@ -50,9 +50,9 @@ RenderRoot::RenderRoot(DOM::NodeImpl* node, KHTMLView *view)
     m_width = m_minWidth;
     m_maxWidth = m_minWidth;
 
-    m_rootWidth=0;
-    m_rootHeight=0;
-
+    m_rootWidth = m_rootHeight = 0;
+    m_viewportWidth = m_viewportHeight = 0;
+    
     setPositioned(true); // to 0,0 :)
 
     m_printingMode = false;
@@ -122,13 +122,11 @@ void RenderRoot::calcMinMaxWidth()
 
 void RenderRoot::layout()
 {
-    //kdDebug(6040) << "RenderRoot::layout()" << endl;
     if (m_printingMode)
        m_minWidth = m_width;
 
-    if(firstChild()) {
+    if(firstChild())
         firstChild()->setLayouted(false);
-    }
 
 #ifdef SPEED_DEBUG
     QTime qt;
@@ -138,40 +136,42 @@ void RenderRoot::layout()
 	recalcMinMaxWidths();
 #ifdef SPEED_DEBUG
     kdDebug() << "RenderRoot::calcMinMax time used=" << qt.elapsed() << endl;
-    // this fixes frameset resizing
     qt.start();
 #endif
 
-    RenderFlow::layout();
 #ifdef SPEED_DEBUG
     kdDebug() << "RenderRoot::layout time used=" << qt.elapsed() << endl;
     qt.start();
 #endif
-    // have to do that before layoutSpecialObjects() to get fixed positioned objects at the right place
-    if (m_view) m_view->resizeContents(docWidth(), docHeight());
-
-    if (!m_printingMode && m_view)
-    {
-        m_height = m_view->visibleHeight();
-        m_width = m_view->visibleWidth();
+    if (!m_printingMode) {
+        m_viewportWidth = m_width = m_view->visibleWidth();
+        m_viewportHeight = m_height = m_view->visibleHeight();
     }
-    else if (!m_view)
-    {
-        m_height = m_rootHeight;
+    else {
         m_width = m_rootWidth;
+        m_height = m_rootHeight;
     }
-    
+
+    RenderFlow::layout();
+
+    if (!m_printingMode) {
+        m_view->resizeContents(docWidth(), docHeight());
+        setWidth( m_viewportWidth = m_view->visibleWidth() );
+        setHeight(  m_viewportHeight = m_view->visibleHeight() );
+    }
+
+
     // ### we could maybe do the call below better and only pass true if the docsize changed.
     layoutSpecialObjects( true );
+
 #ifdef SPEED_DEBUG
     kdDebug() << "RenderRoot::end time used=" << qt.elapsed() << endl;
 #endif
 
     layer()->setHeight(m_height);
     layer()->setWidth(m_width);
-    
+
     setLayouted();
-    //kdDebug(0) << "root: height = " << m_height << endl;
 }
 
 bool RenderRoot::absolutePosition(int &xPos, int &yPos, bool f)
@@ -211,12 +211,17 @@ void RenderRoot::paintObject(QPainter *p, int _x, int _y,
         child = child->nextSibling();
     }
 
-#ifdef BOX_DEBUG
     if (m_view)
     {
         _tx += m_view->contentsX();
         _ty += m_view->contentsY();
     }
+    
+    // 3. paint floats.
+    if (paintPhase == FLOAT_PHASE)
+        paintFloats(p, _x, _y, _w, _h, _tx, _ty);
+        
+#ifdef BOX_DEBUG
     outlineBox(p, _tx, _ty);
 #endif
 
diff --git a/WebCore/khtml/rendering/render_root.h b/WebCore/khtml/rendering/render_root.h
index adaee8a..d7e9c4b 100644
--- a/WebCore/khtml/rendering/render_root.h
+++ b/WebCore/khtml/rendering/render_root.h
@@ -74,6 +74,9 @@ public:
     virtual void setWidth( int width ) { m_rootWidth = m_width = width; }
     virtual void setHeight( int height ) { m_rootHeight = m_height = height; }
 
+    int viewportWidth() const { return m_viewportWidth; }
+    int viewportHeight() const { return m_viewportHeight; }
+    
 protected:
 
     virtual void selectionStartEnd(int& spos, int& epos);
@@ -90,6 +93,9 @@ protected:
     int m_rootWidth;
     int m_rootHeight;
 
+    int m_viewportWidth;
+    int m_viewportHeight;
+    
     // used to ignore viewport width when printing to the printer
     bool m_printingMode;
     bool m_printImages;
diff --git a/WebCore/khtml/rendering/render_style.cpp b/WebCore/khtml/rendering/render_style.cpp
index c7175c1..6106915 100644
--- a/WebCore/khtml/rendering/render_style.cpp
+++ b/WebCore/khtml/rendering/render_style.cpp
@@ -31,7 +31,7 @@
 using namespace khtml;
 
 StyleSurroundData::StyleSurroundData()
-    : margin( Fixed ), padding( Fixed )
+    : margin( Fixed ), padding( Variable )
 {
 }
 
diff --git a/WebCore/khtml/rendering/render_style.h b/WebCore/khtml/rendering/render_style.h
index ec91dbd..10e59a3 100644
--- a/WebCore/khtml/rendering/render_style.h
+++ b/WebCore/khtml/rendering/render_style.h
@@ -383,7 +383,7 @@ public:
 // this applies to decoration_color too
 
 enum EWhiteSpace {
-    NORMAL, PRE, NOWRAP
+    NORMAL, PRE, NOWRAP, KONQ_NOWRAP
 };
 
 enum ETextAlign {
@@ -641,7 +641,6 @@ public:
     bool operator==(const RenderStyle& other) const;
     bool        isFloating() const { return !(noninherited_flags._floating == FNONE); }
     bool        hasMargin() const { return surround->margin.nonZero(); }
-    bool        hasPadding() const { return surround->padding.nonZero(); }
     bool        hasBorder() const { return surround->border.hasBorder(); }
     bool        hasOffset() const { return surround->offset.nonZero(); }
 
@@ -705,7 +704,7 @@ public:
     EUnicodeBidi unicodeBidi() const { return noninherited_flags._unicodeBidi; }
 
     EClear clear() const { return  noninherited_flags._clear; }
-    ETableLayout inheritedLayout() const { return  noninherited_flags._table_layout; }
+    ETableLayout tableLayout() const { return  noninherited_flags._table_layout; }
 
     short colSpan() const { return visual->colspan; }
 
diff --git a/WebCore/khtml/rendering/render_table.cpp b/WebCore/khtml/rendering/render_table.cpp
index 48d4ed7..557c5e3 100644
--- a/WebCore/khtml/rendering/render_table.cpp
+++ b/WebCore/khtml/rendering/render_table.cpp
@@ -6,7 +6,6 @@
  *           (C) 1998 Waldo Bastian (bastian at kde.org)
  *           (C) 1999 Lars Knoll (knoll at kde.org)
  *           (C) 1999 Antti Koivisto (koivisto at kde.org)
- * Copyright (C) 2002 Apple Computer, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -28,11 +27,10 @@
 //#define TABLE_PRINT
 //#define DEBUG_LAYOUT
 //#define BOX_DEBUG
-
 #include "rendering/render_table.h"
+#include "rendering/table_layout.h"
 #include "html/html_tableimpl.h"
 #include "misc/htmltags.h"
-#include "xml/dom_docimpl.h"
 
 #include <kglobal.h>
 
@@ -44,93 +42,67 @@
 
 using namespace khtml;
 
-template class QMemArray<LengthType>;
-
-#define FOR_EACH_CELL(r,c,cell) \
-    for ( unsigned int r = 0; r < totalRows; r++ )                    \
-    {                                                                 \
-        for ( unsigned int c = 0; c < totalCols; c++ )                \
-        {                                                             \
-            RenderTableCell *cell = cells[r][c];             \
-            if (!cell)                                                \
-                continue;                                             \
-            if ( (c < totalCols - 1) && (cell == cells[r][c+1]) )     \
-                continue;                                             \
-            if ( (r < totalRows - 1) && (cells[r+1][c] == cell) )     \
-                continue;
-
-#define END_FOR_EACH } }
-
-
 RenderTable::RenderTable(DOM::NodeImpl* node)
     : RenderFlow(node)
 {
 
     tCaption = 0;
-    _oldColElem = 0;
-    head = 0;
-    foot = 0;
-    firstBody = 0;
-
-    incremental = false;
-    m_maxWidth = 0;
-
+    head = foot = firstBody = 0;
+    tableLayout = 0;
 
     rules = None;
     frame = Void;
+    has_col_elems = false;
+    spacing = 0;
+    padding = 0;
+    needSectionRecalc = false;
+    padding = 0;
 
-    m_cellPadding = -1;
-    
-    row = 0;
-    col = 0;
-
-    maxColSpan = 0;
+    columnPos.resize( 2 );
+    columnPos.fill( 0 );
+    columns.resize( 1 );
+    columns.fill( ColumnStruct() );
 
-    colInfos.setAutoDelete(true);
+    columnPos[0] = 0;
+}
 
-    _currentCol=0;
+RenderTable::~RenderTable()
+{
+    delete tableLayout;
+}
 
-    _lastParentWidth = 0;
+void RenderTable::setStyle(RenderStyle *_style)
+{
+    ETableLayout oldTableLayout = style() ? style()->tableLayout() : TAUTO;
+    if ( _style->display() == INLINE ) _style->setDisplay(INLINE_TABLE);
+    if ( _style->display() != INLINE_TABLE ) _style->setDisplay(TABLE);
+    RenderFlow::setStyle(_style);
 
-    columnPos.resize( 2 );
-    colMaxWidth.resize( 1 );
-    colMinWidth.resize( 1 );
-    colValue.resize(1);
-    colType.resize(1);
-    actColWidth.resize(1);
-    columnPos.fill( 0 );
-    colMaxWidth.fill( 0 );
-    colMinWidth.fill( 0 );
-    colValue.fill(0);
-    colType.fill(Variable);
-    actColWidth.fill(0);
+    // init RenderObject attributes
+    setInline(style()->display()==INLINE_TABLE && !isPositioned());
+    setReplaced(style()->display()==INLINE_TABLE);
 
+    spacing = style()->borderSpacing();
     columnPos[0] = spacing;
 
-    totalCols = 0;   // this should be expanded to the maximum number of cols
-                     // by the first row parsed
-    totalRows = 0;
-    allocRows = 5;   // allocate five rows initially
-    rowInfo.resize( totalRows+1 );
-    memset( rowInfo.data(), 0, (totalRows+1)*sizeof(RowInfo)); // Init to 0.
-
-    cells = new RenderTableCell ** [allocRows];
+    if ( !tableLayout || style()->tableLayout() != oldTableLayout ) {
+	delete tableLayout;
 
-    for ( unsigned int r = 0; r < allocRows; r++ )
-    {
-        cells[r] = new RenderTableCell * [totalCols];
-        memset( cells[r], 0, totalCols * sizeof( RenderTableCell * ));
+	if (style()->tableLayout() == TFIXED ) {
+	    tableLayout = new FixedTableLayout(this);
+#ifdef DEBUG_LAYOUT
+	    kdDebug( 6040 ) << "using fixed table layout" << endl;
+#endif
+	} else
+	    tableLayout = new AutoTableLayout(this);
     }
-    needsCellsRecalc = false;
-    colWidthKnown = false;
-    hasPercent = false;
 }
 
-RenderTable::~RenderTable()
+void RenderTable::position(int x, int y, int, int, int, bool, bool, int)
 {
-    for ( unsigned int r = 0; r < allocRows; r++ )
-        delete [] cells[r];
-    delete [] cells;
+    //for inline tables only
+    m_x = x + marginLeft();
+    m_y = y + marginTop();
 }
 
 short RenderTable::lineHeight(bool b) const
@@ -151,90 +123,50 @@ short RenderTable::baselinePosition(bool b) const
     return RenderFlow::baselinePosition(b);
 }
 
-void RenderTable::setStyle(RenderStyle *_style)
-{
-    RenderFlow::setStyle(_style);
-
-    // init RenderObject attributes
-    // In quirks mode, we will accept display: inline and block as valid
-    // display types for a table object (see www.sundancecatalog.com).
-    // A table therefore should go ahead and check if it's inline as well
-    // as inline-table.
-    bool isTableInline = style()->display() == INLINE_TABLE ||
-                         style()->display() == INLINE;
-    setInline(isTableInline && !isPositioned());
-    setReplaced(isTableInline);
-   
-    spacing = style()->borderSpacing();
-    collapseBorders = style()->borderCollapse();
-}
-
-void RenderTable::position(int x, int y, int, int, int, bool, bool, int)
-{
-    //for inline tables only
-    m_x = x + marginLeft();
-    m_y = y + marginTop();
-}
-
 void RenderTable::addChild(RenderObject *child, RenderObject *beforeChild)
 {
 #ifdef DEBUG_LAYOUT
     kdDebug( 6040 ) << renderName() << "(Table)::addChild( " << child->renderName() << ", " <<
                        (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;
 #endif
+    RenderObject *o = child;
+
     if (child->element() && child->element()->id() == ID_FORM) {
         RenderContainer::addChild(child,beforeChild);
         return;
     }
-            
-    RenderObject *o = child;
-    
+
     switch(child->style()->display())
     {
     case TABLE_CAPTION:
-        tCaption = static_cast<RenderTableCaption *>(child);
+        tCaption = static_cast<RenderFlow *>(child);
         break;
     case TABLE_COLUMN:
     case TABLE_COLUMN_GROUP:
-        {
-	    RenderContainer::addChild(child,beforeChild);
-	    RenderTableCol* colel = static_cast<RenderTableCol *>(child);
-	    if (_oldColElem && _oldColElem->style()->display() == TABLE_COLUMN_GROUP)
-		_currentCol = _oldColElem->lastCol();
-	    _oldColElem = colel;
-	    colel->setStartCol(_currentCol);
-	    if ( colel->span() != 0 ) {
-		if (child->style()->display() == TABLE_COLUMN)
-		    _currentCol++;
-		else
-		    _currentCol+=colel->span();
-		addColInfo(colel);
-	    }
-	    incremental = true;
-	    colel->setTable(this);
-	}
-	child->setLayouted( false );
-	child->setMinMaxKnown( false );
+	RenderContainer::addChild(child,beforeChild);
+	has_col_elems = true;
         return;
     case TABLE_HEADER_GROUP:
-        if(incremental && !columnPos[totalCols]);// calcColWidth();
-//      setTHead(static_cast<RenderTableSection *>(child));
+	if ( !head )
+	    head = static_cast<RenderTableSection *>(child);
+	else if ( !firstBody )
+            firstBody = static_cast<RenderTableSection *>(child);
         break;
     case TABLE_FOOTER_GROUP:
-        if(incremental && !columnPos[totalCols]);// calcColWidth();
-//      setTFoot(static_cast<RenderTableSection *>(child));
-        break;
+	if ( !foot ) {
+	    foot = static_cast<RenderTableSection *>(child);
+	    break;
+	}
+	// fall through
     case TABLE_ROW_GROUP:
-        if(incremental && !columnPos[totalCols]);// calcColWidth();
         if(!firstBody)
             firstBody = static_cast<RenderTableSection *>(child);
         break;
     default:
-        if ( !beforeChild )
-            beforeChild = lastChild();
-        if ( beforeChild && beforeChild->isAnonymousBox() )
-            o = beforeChild;
-        else {
+        if ( !beforeChild && lastChild() &&
+	     lastChild()->isTableSection() && lastChild()->isAnonymousBox() ) {
+            o = lastChild();
+        } else {
 	    RenderObject *lastBox = beforeChild;
 	    while ( lastBox && lastBox->parent()->isAnonymousBox() &&
 		    !lastBox->isTableSection() && lastBox->style()->display() != TABLE_CAPTION )
@@ -243,11 +175,13 @@ void RenderTable::addChild(RenderObject *child, RenderObject *beforeChild)
 		lastBox->addChild( child, beforeChild );
 		return;
 	    } else {
-//          kdDebug( 6040 ) << "creating anonymous table section" << endl;
+		if ( beforeChild && !beforeChild->isTableSection() )
+		    beforeChild = 0;
+  		//kdDebug( 6040 ) << this <<" creating anonymous table section beforeChild="<< beforeChild << endl;
 		o = new (renderArena()) RenderTableSection(0 /* anonymous */);
 		RenderStyle *newStyle = new RenderStyle();
 		newStyle->inheritFrom(style());
-		newStyle->setDisplay(TABLE_ROW_GROUP);
+                newStyle->setDisplay(TABLE_ROW_GROUP);
 		o->setStyle(newStyle);
 		o->setIsAnonymousBox(true);
 		addChild(o, beforeChild);
@@ -259,786 +193,10 @@ void RenderTable::addChild(RenderObject *child, RenderObject *beforeChild)
         return;
     }
     RenderContainer::addChild(child,beforeChild);
-    child->setTable(this);
-}
-
-void RenderTable::startRow()
-{
-    while ( col < totalCols && cells[row][col] != 0 )
-        col++;
-    if ( col )
-        row++;
-    col = 0;
-    if(row > totalRows) totalRows = row;
-    if (totalRows == 0)
-        totalRows = 1; // Go ahead and acknowledge that we have one row. -dwh.
-}
-
-void RenderTable::closeRow()
-{
-    while ( col < totalCols && cells[row][col] != 0L )
-        col++;
-
-    if (col<=0) return;
-
-    RenderTableCell* cell = cells[row][col-1];
-
-    if (!cell) return;
-}
-
-void RenderTable::addCell( RenderTableCell *cell )
-{
-    while ( col < totalCols && cells[row][col] != 0L )
-        col++;
-    setCells( row, col, cell );
-
-    col++;
-}
-
-
-void RenderTable::setCells( unsigned int r, unsigned int c,
-                                     RenderTableCell *cell )
-{
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "setCells: span = " << cell->rowSpan() << "/" << cell->colSpan() << " pos = " << r << "/" << c << endl;
-#endif
-    cell->setRow(r);
-    cell->setCol(c);
-
-    unsigned int endRow = r + cell->rowSpan();
-    unsigned int endCol = c + cell->colSpan();
-
-    if ( endCol > totalCols )
-        addColumns( endCol - totalCols );
-
-    if ( endRow >= allocRows )
-        addRows( endRow - allocRows + 10 );
-
-    if ( endRow > totalRows )
-        totalRows = endRow;
-
-    for ( ; r < endRow; r++ ) {
-        for ( unsigned int tc = c; tc < endCol; tc++ ) {
-            cells[r][tc] = cell;
-        }
-    }
-}
-
-void RenderTable::addRows( int num )
-{
-    RenderTableCell ***newRows =
-        new RenderTableCell ** [allocRows + num];
-    memcpy( newRows, cells, allocRows * sizeof(RenderTableCell **) );
-    delete [] cells;
-    cells = newRows;
-
-    for ( unsigned int r = allocRows; r < allocRows + num; r++ )
-    {
-        cells[r] = new RenderTableCell * [totalCols];
-        memset( cells[r], 0, totalCols * sizeof( RenderTableCell * ));
-    }
-
-    allocRows += num;
-}
-
-void RenderTable::addColumns( int num )
-{
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "addColumns() totalCols=" << totalCols << " new=" << num << endl;
-#endif
-    RenderTableCell **newCells;
-
-    int newCols = totalCols + num;
-    // resize the col structs to the number of columns
-    columnPos.resize(newCols+1);
-    memset( columnPos.data() + totalCols + 1, 0, num*sizeof(int));
-    colMaxWidth.resize(newCols);
-    memset( colMaxWidth.data() + totalCols , 0, num*sizeof(int));
-    colMinWidth.resize(newCols);
-    memset( colMinWidth.data() + totalCols , 0, num*sizeof(int));
-    colValue.resize(newCols);
-    memset( colValue.data() + totalCols , 0, num*sizeof(int));
-    colType.resize(newCols);
-    memset( colType.data() + totalCols , 0, num*sizeof(LengthType));
-    actColWidth.resize(newCols);
-    memset( actColWidth.data() + totalCols , 0, num*sizeof(LengthType));
-
-    for ( unsigned int r = 0; r < allocRows; r++ )
-    {
-        newCells = new RenderTableCell * [newCols];
-        memcpy( newCells, cells[r],
-                totalCols * sizeof( RenderTableCell * ) );
-        memset( newCells + totalCols, 0,
-                num * sizeof( RenderTableCell * ) );
-        delete [] cells[r];
-        cells[r] = newCells;
-    }
-
-    int mSpan = newCols;
-
-    colInfos.resize(mSpan);
-
-    for ( unsigned int c =0 ; c < totalCols; c++ )
-    {
-        colInfos[c]->resize(newCols);
-    }
-    for ( unsigned int c = totalCols; (int)c < newCols; c++ )
-    {
-        colInfos.insert(c, new ColInfoLine(newCols-c+1));
-    }
-
-    totalCols = newCols;
-}
-
-
-void RenderTable::recalcColInfos()
-{
-//    kdDebug(0) << "RenderTable::recalcColInfos()" << endl;
-    for (int s=0 ; s<maxColSpan; s++)
-    {
-        for (unsigned int c=0 ; c<totalCols; c++)
-            if (c<colInfos[s]->size())
-                colInfos[s]->remove(c);
-    }
-
-    maxColSpan = 0;
-
-    FOR_EACH_CELL(r,c,cell)
-        addColInfo(cell);
-    END_FOR_EACH
-}
-
-void RenderTable::recalcColInfo( ColInfo *col )
-{
-    //qDebug("------------- recalcColinfo: line=%d, span=%d", col->start, col->span-1);
-
-    KHTMLAssert( colInfos[col->span-1]->at(col->start) == col );
-
-    // We need to recalc all the members of the column. -dwh
-    bool needRecalc = true;
-
-    // add table-column if exists
-    RenderObject *child = firstChild();
-    while( child ) {
-	if ( child->style()->display() == TABLE_COLUMN ||
-	     child->style()->display() == TABLE_COLUMN_GROUP ) {
-	    RenderTableCol *tc = static_cast<RenderTableCol *>(child);
-	    if ( tc->span() == col->span && tc->col() == col->start ) {
-	        if (needRecalc) {
-		    needRecalc = false;
-                    col->needsRecalc();
-	        }
-		addColInfo( tc );
-		break;
-	    }
-	} else {
-	    break;
-	}
-	child = child->nextSibling();
-    }
-
-    // now the cells
-    for ( unsigned int r = 0; r < totalRows; r++ ) {
-	RenderTableCell *cell = cells[r][col->start];
-	if ( cell && cell->colSpan() == col->span ) {
-	    if (needRecalc) {
-	        needRecalc = false;
-                col->needsRecalc();
-	    }
-	    addColInfo(cell, false);
-        }
-    }
-    
-    if (needRecalc)
-        // Null out and delete the column.
-        colInfos[col->span-1]->remove(col->start);
-
-    setMinMaxKnown( false );
-
-    //qDebug("------------- end recalcColinfo");
-}
-
-
-void RenderTable::addColInfo(RenderTableCol *colel)
-{
-
-    int _startCol = colel->col();
-    int span = colel->span();
-    int _minSize=0;
-    int _maxSize=0;
-    Length _width = colel->style()->width();
-    if (_width.type==Fixed) {
-        _maxSize=_width.value;
-	_minSize=_width.value;
-    }
-
-    for (int n=0; n<span; ++n) {
-#ifdef TABLE_DEBUG
-        kdDebug( 6040 ) << "COL Element" << endl;
-        kdDebug( 6040 ) << "    startCol=" << _startCol << " span=" << span << endl;
-        kdDebug( 6040 ) << "    min=" << _minSize << " max=" << _maxSize << " val=" << _width.value << endl;
-#endif
-        addColInfo(_startCol+n, 1 , _minSize, _maxSize, _width ,0);
-    }
-
-}
-
-void RenderTable::addColInfo(RenderTableCell *cell, bool allowRecalc)
-{
-
-    int _startCol = cell->col();
-    int _colSpan = cell->colSpan();
-    int _minSize = cell->minWidth();
-    int _maxSize = cell->maxWidth();
-
-#if 0
-    // We do need to implement "collapse borders", but just doing this
-    // fudge on the calculation of the column widths is not enough to do so.
-    // This alone simply makes borders draw incorrectly.
-    if (collapseBorders)
-    {
-        int bw = cell->borderLeft() + cell->borderRight();
-        _minSize -= bw;
-        _maxSize -= bw;
-    }
-#endif
-
-    Length _width = cell->style()->width();
-    addColInfo(_startCol, _colSpan, _minSize, _maxSize, _width ,cell, allowRecalc);
-}
-
-void RenderTable::addColInfo(int _startCol, int _colSpan,
-                                      int _minSize, int _maxSize,
-                                      Length _width, RenderTableCell* _cell, bool allowRecalc )
-{
-    // Netscape ignores width values of "0" or "0%"
-    if ( style()->htmlHacks() && _width.value == 0 && (_width.type == Percent || _width.type == Fixed) )
-	    _width = Length();
-
-    if (_startCol + _colSpan > (int) totalCols)
-        addColumns(totalCols - _startCol + _colSpan);
-
-    ColInfo* col = colInfos[_colSpan-1]->at(_startCol);
-
-    bool changed = false;
-    bool recalc = false;
-
-    if (!col) {
-        col = new ColInfo;
-        colInfos[_colSpan-1]->insert(_startCol,col);
-    }
-    
-    if (col->needRecalc) {
-        col->needRecalc = false;
-        col->span = _colSpan;
-        col->start = _startCol;
-        col->minCell = _cell;
-        col->maxCell = _cell;
-	col->min = _minSize;
-        col->max = _maxSize;
-        if (_colSpan>maxColSpan)
-            maxColSpan=_colSpan;
-        col->type = _width.type;
-	col->value = _width.value;
-	col->widthCell = _cell;
-
-	changed = true;
-    } else {
-	if (_minSize != col->min) {
-	    if ( allowRecalc && col->minCell == _cell ) {
-		recalc = true;
-	    } else if ( _minSize > col->min ) {
-		col->min = _minSize;
-		col->minCell = _cell;
-		changed = true;
-	    }
-	}
-	if (_maxSize != col->max) {
-	    if ( allowRecalc && col->maxCell == _cell ) {
-		recalc = true;
-	    } else if (_maxSize > col->max) {
-		col->max = _maxSize;
-		col->maxCell = _cell;
-		changed = true;
-	    }
-	}
-
-	// Fixed width is treated as variable
-
-	if (_width.type == col->type && _width.value > col->value ) {
-	    if ( allowRecalc && col->widthCell == _cell ) {
-		recalc = true;
-	    } else {
-		col->value = _width.value;
-		col->widthCell = _cell;
-		changed = true;
-	    }
-	} else if ( (_width.type > int(col->type) && (!(_width.type==Fixed) || (int(col->type)<=Variable)))
-		    || ( col->type == Fixed && !(_width.type==Variable)) ) {
-	    if ( allowRecalc && col->widthCell == _cell ) {
-		recalc = true;
-	    } else {
-		col->type = _width.type;
-		col->value = _width.value;
-		col->widthCell = _cell;
-		changed = true;
-	    }
-	}
-    }
-    
-    if ( recalc )
-        recalcColInfo( col );
-
-    if ( changed )
-	setMinMaxKnown(false);
-
-    if ( recalc || changed )
-	colWidthKnown = false;
-
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "(" << this << "):addColInfo():" << endl;
-    kdDebug( 6040 ) << "    startCol=" << col->start << " span=" << col->span << endl;
-    kdDebug( 6040 ) << "    min=" << col->min << " max=" << col->max << endl;
-    kdDebug( 6040 ) << "    type=" << col->type << " width=" << col->value << endl;
-#endif
-
-}
-
-void RenderTable::spreadSpanMinMax(int col, int span, int distmin,
-    int distmax, LengthType type)
-{
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "RenderTable::spreadSpanMinMax() " << type << " " << distmin << " " << distmax << endl;
-#endif
-
-    if (distmin<1)
-        distmin=0;
-    if (distmax<1)
-        distmax=0;
-    if (distmin<1 && distmax<1)
-        return;
-
-
-    bool hasUsableCols=false;
-    int tmax=distmax;
-    int tmin=distmin;
-    int c;
-
-    for (c=col; c < col+span ; ++c)
-    {
-
-        if (colType[c]<=type || (type == Variable && distmax==0))
-        {
-            hasUsableCols=true;
-            break;
-        }
-    }
-
-    if (hasUsableCols) {
-        // spread span maxWidth
-        for (int i = LengthType(Variable); i <= int(Fixed) && i <= type && tmax; ++i)
-            tmax = distributeMaxWidth(tmax,type,LengthType(i),col,span);
-
-
-        // spread span minWidth
-        for (int i = LengthType(Variable); i <= int(Fixed) && i <= type && tmin; ++i)
-            tmin = distributeMinWidth(tmin,type,LengthType(i),col,span,true);
-
-        // force spread rest of the minWidth
-        for (int i = LengthType(Variable); i <= int(Fixed) && tmin; ++i)
-            tmin = distributeMinWidth(tmin,type,LengthType(i),col,span,false);
-
-        for (int c=col; c < col+span ; ++c)
-            colMaxWidth[c]=KMAX(colMinWidth[c],colMaxWidth[c]);
-    }
-}
-
-
-int RenderTable::distributeMinWidth(int distrib, LengthType distType,
-            LengthType toType, int start, int span, bool mlim )
-{
-//    kdDebug( 6040 ) << "MINDIST, " << distrib << " pixels of type " << distType << " to type " << toType << " cols sp=" << span << " " << endl;
-
-    int olddis=0;
-    int c=start;
-    int totper=0;
-
-    int tdis = distrib;
-
-    if (!mlim)
-    {
-        // first target unused columns
-        for(; c<start+span; ++c)
-        {
-            if (colInfos[0]->at(c)==0)
-            {
-                colMinWidth[c]+=tdis;
-                colType[c]=distType;
-                tdis=0;
-                break;
-            }
-        }
-    }
-
-    if (toType==Percent || toType==Relative)
-        for (int n=start;n<start+span;n++)
-            if (colType[n]==Percent || colType[n]==Relative) totper += colValue[n];
-
-    c=start;
-    while(tdis>0)
-    {
-//      kdDebug( 6040 ) << c << ": ct=" << colType[c] << " min=" << colMinWidth[c]
-//                << " max=" << colMaxWidth[c] << endl;
-        if (colType[c]==toType || (mlim && colMaxWidth[c]-colMinWidth[c]>0))
-        {
-            int delta = distrib/span;
-            if (totper)
-                delta=(distrib * colValue[c])/totper;
-            if (mlim)
-                delta = KMIN(delta,colMaxWidth[c]-colMinWidth[c]);
-
-            delta = KMIN(tdis,delta);
-
-            if (delta==0 && tdis && (!mlim || colMaxWidth[c]>colMinWidth[c]))
-                delta=1;
-
-//            kdDebug( 6040 ) << "delta=" << delta << endl;
-
-            colMinWidth[c]+=delta;
-            if (mlim)
-                colType[c]=distType;
-            tdis-=delta;
-        }
-        if (++c==start+span)
-        {
-            c=start;
-            if (olddis==tdis)
-                break;
-            olddis=tdis;
-        }
-    }
-
-    return tdis;
 }
 
 
 
-int RenderTable::distributeMaxWidth(int distrib, LengthType/* distType*/,
-            LengthType toType, int start, int span)
-{
-//    kdDebug( 6040 ) << "MAXDIST, " << distrib << " pixels of type " << distType << " to type " << toType << " cols sp=" << span << " " << endl;
-    int olddis=0;
-    int c=start;
-
-    int tdis = distrib;
-
-    // spread span maxWidth evenly
-    c=start;
-    while(tdis>0)
-    {
-//      kdDebug( 6040 ) << c << ": ct=" << colType[c] << " min=" << colMinWidth[c]
-//                << " max=" << colMaxWidth[c] << endl;
-
-        if (colType[c]==toType)
-        {
-            colMaxWidth[c]+=distrib/span;
-            tdis-=distrib/span;
-            if (tdis<span)
-            {
-                colMaxWidth[c]+=tdis;
-                tdis=0;
-            }
-        }
-        if (++c==start+span)
-        {
-            c=start;
-            if (olddis==tdis)
-                break;
-            olddis=tdis;
-        }
-    }
-    return tdis;
-}
-
-
-
-void RenderTable::calcSingleColMinMax(int c, ColInfo* col)
-{
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "RenderTable::calcSingleColMinMax()" << endl;
-#endif
-
-    int span=col->span;
-    int smin = col->min;
-    int smax = col->max;
-
-    if (span==1)
-    {
-      //kdDebug( 6040 ) << "col (s=1) c=" << c << ",m=" << smin << ",x=" << smax << endl;
-        colMinWidth[c] = smin;
-        colMaxWidth[c] = smax;
-        colValue[c] = col->value;
-        colType[c] = col->type;
-    }
-    else
-    {
-        int oldmin=0;
-        int oldmax=0;
-        for (int o=c; o<c+span; ++o)
-        {
-            oldmin+=colMinWidth[o];
-            oldmax+=colMaxWidth[o];
-        }
-        int spreadmin = smin-oldmin-(span-1)*spacing;
-//        kdDebug( 6040 ) << "colmin " << smin  << endl;
-//        kdDebug( 6040 ) << "oldmin " << oldmin  << endl;
-//        kdDebug( 6040 ) << "oldmax " << oldmax  << endl;
-//      kdDebug( 6040 ) << "spreading span " << spreadmin  << endl;
-        spreadSpanMinMax
-            (c, span, spreadmin, 0 , col->type);
-    }
-
-}
-
-void RenderTable::calcFinalColMax(int c, ColInfo* col)
-{
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "RenderTable::calcPercentRelativeMax()" << endl;
-#endif
-    int span=col->span;
-
-    int oldmax=0;
-    int oldmin=0;
-
-    for (int o=c; o<c+span; ++o)
-    {
-        oldmax+=colMaxWidth[o];
-        oldmin+=colMinWidth[o];
-    }
-
-    int smax = col->max;
-
-    if (col->type == Percent)
-    {
-        smax = m_width * col->value / KMAX(100u,totalPercent);
-    }
-    else if (col->type == Relative && totalRelative)
-    {
-        smax = m_width * col->value / totalRelative;
-    }
-
-    smax = KMAX(smax,oldmin);
-
-//    kdDebug( 6040 ) << "smin " << smin << " smax " << smax << " span " << span << endl;
-    if (span==1)
-    {
-//       kdDebug( 6040 ) << "col (s=1) c=" << c << ",m=" << smin << ",x=" << smax << endl;
-       colMaxWidth[c] = smax;
-       colType[c] = col->type;
-    }
-    else
-    {
-        int spreadmax = smax-oldmax-(span-1)*spacing;
-//      kdDebug( 6040 ) << "spreading span " << spreadmax << endl;
-        spreadSpanMinMax
-            (c, span, 0, spreadmax, col->type);
-    }
-
-}
-
-
-
-void RenderTable::calcColMinMax()
-{
-// Calculate minmimum and maximum widths for all
-// columns.
-// Calculate min and max width for the table.
-
-    // PHASE 1, prepare
-
-    colMinWidth.fill(0);
-    colMaxWidth.fill(0);
-
-    int availableWidth = containingBlockWidth();
-
-    int realMaxWidth=spacing;
-
-    int* spanPercent = new int[maxColSpan];
-    int* spanPercentMax = new int[maxColSpan];
-
-    LengthType widthType = style()->width().type;
-
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "RenderTable(" << this << ")::calcColMinMax(), maxCelSpan" << maxColSpan << " totalCols " << totalCols << " widthtype=" << widthType << " widthval=" << style()->width().value << endl;
-#endif
-
-    Length l;
-    if ( ( l = style()->marginLeft() ).isFixed() )
-        availableWidth -= QMAX( l.value, 0 );
-    if ( ( l = style()->marginRight() ).isFixed() )
-        availableWidth -= QMAX( l.value, 0 );
-
-    availableWidth -= QMAX( style()->borderLeftWidth(), 0 );
-    availableWidth -= QMAX( style()->borderRightWidth(), 0 );
-    // PHASE 2, calculate simple minimums and maximums
-    for ( unsigned int s=0;  (int)s<maxColSpan ; ++s)
-    {
-        ColInfoLine* spanCols = colInfos[s];
-
-        int spanMax=0;
-        spanPercentMax[s] = spacing;
-        spanPercent[s] = 0;
-
-        for ( unsigned int c=0; c<totalCols-s; ++c)
-        {
-            ColInfo* col;
-            col = spanCols->at(c);
-
-            if (!col || col->span==0)
-                continue;
-#ifdef TABLE_DEBUG
-            kdDebug( 6040 ) << " s=" << s << " c=" << c << " min=" << col->min << " value=" << col->value  <<
-                        " max="<<col->max<< endl;
-#endif
-
-            spanMax += col->max + spacing;
-
-            if (col->type==Percent)
-            {
-                spanPercentMax[s] += col->max+spacing;
-                spanPercent[s] += col->value;
-            }
-
-            calcSingleColMinMax(c, col);
-
-            if ( col->span>1 && widthType != Percent
-                && (col->type==Variable || col->type==Fixed))
-            {
-                calcFinalColMax(c, col);
-            }
-
-        }
-
-        // this should be some sort of generic path algorithm
-        // but we'll just hack it for now
-        if (spanMax>realMaxWidth)
-            realMaxWidth=spanMax;
-    }
-
-    // PHASE 3, calculate table width
-
-    totalPercent=0;
-    totalRelative=0;
-
-    int minPercent=0;
-    int maxPercent=0;
-
-    int minRel=0;
-    int minVar=0;
-    int maxRel=0;
-    int maxVar=0;
-    hasPercent=false;
-    bool hasRel=false;
-    bool hasVar=false;
-
-    int maxPercentColumn=0;
-    int maxTentativePercentWidth=0;
-
-    m_minWidth = spacing;
-    m_maxWidth = spacing;
-
-    for(int i = 0; i < (int)totalCols; i++)
-    {
-        m_minWidth += colMinWidth[i] + spacing;
-        m_maxWidth += colMaxWidth[i] + spacing;
-
-        switch(colType[i])
-        {
-        case Percent:
-            if (!hasPercent){
-                hasPercent=true;
-                minPercent=maxPercent=spacing;
-            }
-            totalPercent += colValue[i];
-
-            maxPercentColumn = KMAX(colValue[i],maxPercentColumn);
-
-            minPercent += colMinWidth[i] + spacing;
-            maxPercent += colMaxWidth[i] + spacing;
-
-            maxTentativePercentWidth = KMAX(colValue[i]==0?0:colMaxWidth[i]*100/colValue[i],
-                    maxTentativePercentWidth);
-            break;
-        case Relative:
-            if (!hasRel){
-                hasRel=true;
-                minRel=maxRel=spacing;
-            }
-            totalRelative += colValue[i] ;
-            minRel += colMinWidth[i] + spacing;
-            maxRel += colMaxWidth[i] + spacing;
-            break;
-        case Variable:
-        case Fixed:
-        default:
-            if (!hasVar){
-                hasVar=true;
-                minVar=maxVar=spacing;
-            }
-            minVar += colMinWidth[i] + spacing;
-            maxVar += colMaxWidth[i] + spacing;
-        }
-
-    }
-
-    for ( int s=0; s<maxColSpan ; ++s)
-    {
-        maxPercent = KMAX(spanPercentMax[s],maxPercent);
-        totalPercent = KMAX(spanPercent[s],int(totalPercent));
-    }
-    delete[] spanPercentMax;
-    delete[] spanPercent;
-
-    if (widthType <= Relative && hasPercent) {
-	int tot = KMIN(100u, totalPercent );
-
-        if (tot>0)
-    	    m_maxWidth = maxPercent*100/tot;
-
-        if (tot<100)
-            m_maxWidth = KMAX( short((maxVar+maxRel)*100/(100-tot)), m_maxWidth );
-        else if (hasRel || hasVar || ((int)totalPercent>maxPercentColumn && maxPercentColumn>=100))
-            m_maxWidth = 10000;
-        else if (totalPercent>0)
-            m_maxWidth = KMAX(short(maxTentativePercentWidth*100/totalPercent), m_maxWidth);
-
-    }
-
-
-
-    // PHASE 5, set table min and max to final values
-
-    if(widthType == Fixed) {
-	m_width = style()->width().value;
-	if ( m_width < m_minWidth )
-	    m_width = m_minWidth;
-        m_minWidth = m_maxWidth = m_width;
-    } else {
-        if (realMaxWidth > m_maxWidth)
-            m_maxWidth = realMaxWidth;
-    }
-
-    m_minWidth += borderLeft() + borderRight();
-    m_maxWidth += borderLeft() + borderRight();
-
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "TABLE width=" << m_width <<
-                " m_minWidth=" << m_minWidth <<
-                " m_maxWidth=" << m_maxWidth <<
-                " realMaxWidth=" << realMaxWidth << endl;
-#endif
-}
-
 void RenderTable::calcWidth()
 {
     if ( isPositioned() ) {
@@ -1049,21 +207,20 @@ void RenderTable::calcWidth()
     int availableWidth = cb->contentWidth();
 
     LengthType widthType = style()->width().type;
-    if(widthType > Relative) {
-        // Percent or fixed table
+    if(widthType > Relative && style()->width().value > 0) {
+	// Percent or fixed table
         m_width = style()->width().minWidth( availableWidth );
         if(m_minWidth > m_width) m_width = m_minWidth;
-        //kdDebug( 6040 ) << "1 width=" << m_width << " minWidth=" << m_minWidth << " availableWidth=" << availableWidth << " " << endl;
-    } else if (hasPercent) {
-        m_width = KMIN(short( availableWidth ),m_maxWidth);
-//        kdDebug( 6040 ) << "width=" << m_width << " maxPercent=" << maxPercent << " maxVar=" << maxVar << " " << endl;
+	//kdDebug( 6040 ) << "1 width=" << m_width << " minWidth=" << m_minWidth << " availableWidth=" << availableWidth << " " << endl;
     } else {
         m_width = KMIN(short( availableWidth ),m_maxWidth);
     }
 
     // restrict width to what we really have in case we flow around floats
-    if ( style()->flowAroundFloats() && cb->isFlow() )
-	m_width = QMIN( static_cast<RenderFlow *>(cb)->lineWidth( m_y ), m_width );
+    if ( style()->flowAroundFloats() && cb->isFlow() ) {
+	availableWidth = static_cast<RenderFlow *>(cb)->lineWidth( m_y );
+	m_width = QMIN( availableWidth, m_width );
+    }
 
     m_width = KMAX (m_width, m_minWidth);
 
@@ -1071,390 +228,55 @@ void RenderTable::calcWidth()
     m_marginLeft=0;
 
     calcHorizontalMargins(style()->marginLeft(),style()->marginRight(),availableWidth);
-
-    // PHASE 4, calculate maximums for percent and relative columns. We can't do this in
-    // the minMax calculations, as we do not have the correct table width there.
-
-    for ( unsigned int s=0;  (int)s<maxColSpan ; ++s) {
-        ColInfoLine* spanCols = colInfos[s];
-        for ( unsigned int c=0; c<totalCols-s; ++c) {
-            ColInfo* col;
-            col = spanCols->at(c);
-
-            if (!col || col->span==0)
-                continue;
-            if (col->type==Variable || col->type==Fixed)
-                continue;
-
-            calcFinalColMax(c, col);
-        }
-    }
-}
-
-void RenderTable::calcColWidth(void)
-{
-
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "START calcColWidth() this = " << this << endl;
-    kdDebug( 6040 ) << "maxColSpan = " << maxColSpan << endl;
-#endif
-
-    colWidthKnown = true;
-
-    if (totalCols==0)
-        return;
-
-    /*
-     * Set actColWidth[] to column minimums, it will
-     * grow from there.
-     * Collect same statistics for future use.
-     */
-
-    int actWidth = spacing + borderLeft() + borderRight();
-
-    int minFixed = 0;
-    int minPercent = 0;
-    int minRel = 0;
-    int minVar = 0;
-
-    int maxFixed = 0;
-    int maxPercent = 0;
-    int maxRel = 0;
-    int maxVar = 0;
-
-    int numFixed = 0;
-    int numPercent = 0;
-    int numRel = 0;
-    int numVar = 0;
-
-    actColWidth.fill(0);
-
-    unsigned int i;
-    for(i = 0; i < totalCols; i++)
-    {
-        actColWidth[i] = colMinWidth[i];
-        actWidth += actColWidth[i] + spacing;
-
-        switch(colType[i])
-        {
-        case Fixed:
-            minFixed += colMinWidth[i];
-            maxFixed += colMaxWidth[i];
-            numFixed++;
-            break;
-        case Percent:
-            minPercent += colMinWidth[i];
-            maxPercent += colMaxWidth[i];
-            numPercent++;
-            break;
-        case Relative:
-            minRel += colMinWidth[i];
-            maxRel += colMaxWidth[i];
-            numRel++;
-            break;
-        case Variable:
-        default:
-            minVar += colMinWidth[i];
-            maxVar += colMaxWidth[i];
-            numVar++;
-        }
-
-    }
-
-#ifdef TABLE_DEBUG
-    for(int i = 0; i < (int)totalCols; i++)
-    {
-        kdDebug( 6040 ) << "Start->target " << i << ": " << actColWidth[i] << "->" << colMaxWidth[i] << " type=" << colType[i] << endl;
-    }
-#endif
-
-    int toAdd = m_width - actWidth;      // what we can add
-
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "toAdd = width - actwidth: " << toAdd << " = " << m_width << " - " << actWidth << endl;
-#endif
-
-    /*
-     * distribute the free width among the columns so that
-     * they reach their max width.
-     * Order: percent->fixed->relative->variable
-     */
-
-    toAdd = distributeWidth(toAdd,Percent,numPercent);
-    toAdd = distributeWidth(toAdd,Fixed,numFixed);
-    toAdd = distributeWidth(toAdd,Relative,numRel);
-    toAdd = distributeWidth(toAdd,Variable,numVar);
-
-#ifdef TABLE_DEBUG
-    for(int i = 0; i < (int)totalCols; i++)
-    {
-        kdDebug( 6040 ) << "distributeWidth->target " << i << ": " << actColWidth[i] << "->" << colMaxWidth[i] << " type=" << colType[i] << endl;
-    }
-#endif
-
-    /*
-     * Some width still left?
-     * Reverse order, variable->relative->percent
-     */
-
-    if ( numVar ) toAdd = distributeRest(toAdd,Variable,maxVar);
-    if ( numRel ) toAdd = distributeRest(toAdd,Relative,maxRel);
-    if ( numPercent ) toAdd = distributeRest(toAdd,Percent,maxPercent);
-    if ( numFixed ) toAdd = distributeRest(toAdd,Fixed,maxFixed);
-
-#ifdef TABLE_DEBUG
-    for(int i = 0; i < (int)totalCols; i++)
-    {
-        kdDebug( 6040 ) << "distributeRest->target " << i << ": " << actColWidth[i] << "->" << colMaxWidth[i] << " type=" << colType[i] << endl;
-    }
-#endif
-    /*
-     * If something remains, put it to the last column
-     */
-    actColWidth[totalCols-1] += toAdd;
-
-    /*
-     * Calculate the placement of colums
-     */
-
-    columnPos.fill(0);
-    columnPos[0] = spacing;
-    for(i = 1; i <= totalCols; i++)
-    {
-        columnPos[i] += columnPos[i-1] + actColWidth[i-1] + spacing;
-#ifdef TABLE_DEBUG
-        kdDebug( 6040 ) << "Actual width col " << i << ": " << actColWidth[i-1] << " pos = " << columnPos[i-1] << endl;
-#endif
-    }
-
-#ifdef TABLE_DEBUG
-    if(m_width - borderLeft() - borderLeft() != columnPos[totalCols] )
-        kdDebug( 6040 ) << "========> table layout error!!! <===============================" << endl;
-    kdDebug( 6040 ) << "total width = " << m_width << " colpos = " << columnPos[totalCols] << endl;
-#endif
-
-}
-
-
-int RenderTable::distributeWidth(int distrib, LengthType type, int typeCols )
-{
-    int olddis=0;
-    int c=0;
-
-    int tdis = distrib;
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "DISTRIBUTING " << distrib << " pixels to type " << type << " cols" << endl;
-#endif
-
-    while(tdis>0)
-    {
-        if (colType[c]==type)
-        {
-            int delta = KMIN(distrib/typeCols,colMaxWidth[c]-actColWidth[c]);
-            delta = KMIN(tdis,delta);
-            if (delta==0 && tdis && colMaxWidth[c]>actColWidth[c])
-                delta=1;
-            actColWidth[c]+=delta;
-            tdis-=delta;
-        }
-        if (++c == (int)totalCols)
-        {
-            c=0;
-            if (olddis==tdis)
-                break;
-            olddis=tdis;
-        }
-    }
-    return tdis;
-}
-
-
-int RenderTable::distributeRest(int distrib, LengthType type, int divider )
-{
-    if ( !divider )
-	return distrib;
-
-#ifdef TABLE_DEBUG
-    kdDebug( 6040 ) << "DISTRIBUTING rest, " << distrib << " pixels to type " << type << " cols" << endl;
-#endif
-
-    int olddis=0;
-    int c=0;
-
-    int tdis = distrib;
-
-    while(tdis>0)
-    {
-        if (colType[c]==type)
-        {
-            int delta = colMaxWidth[c] * distrib / divider;
-            delta=KMIN(delta,tdis);
-            actColWidth[c] += delta;
-            tdis -= delta;
-        }
-        if (++c == (int)totalCols)
-        {
-            c=0;
-            if (olddis==tdis)
-                break;
-            olddis=tdis;
-        }
-    }
-    return tdis;
-}
-
-
-void RenderTable::calcRowHeight(int r)
-{
-    unsigned int c;
-    int indx;//, borderExtra = border ? 1 : 0;
-    RenderTableCell *cell;
-
-    rowInfo.resize( totalRows+1 );
-    rowInfo[0].height =  spacing + borderTop();
-    rowInfo[0].percentage = 0;
-    
-  //int oldheight = rowHeights[r+1] - rowHeights[r];
-    rowInfo[r+1].height = rowInfo[r+1].percentage = 0;
-
-    int baseline=0;
-    int bdesc=0;
-    int ch;
-
-    for ( c = 0; c < totalCols; c++ )
-    {
-        if ( ( cell = cells[r][c] ) == 0 )
-            continue;
-        if ( c < totalCols - 1 && cell == cells[r][c+1] )
-            continue;
-        if ( r < (int)totalRows - 1 && cells[r+1][c] == cell )
-            continue;
-
-        if ( ( indx = r - cell->rowSpan() + 1 ) < 0 )
-            indx = 0;
-
-        Length height = cell->style()->height();
-        ch = height.width(0);
-        if ( cell->height() > ch)
-            ch = cell->height();
-
-        if (height.isPercent() && height.value > rowInfo[r+1].percentage)
-            rowInfo[r+1].percentage = height.value;
-            
-        int rowPos = rowInfo[ indx ].height + ch +
-             spacing ; // + padding
-
-        if ( rowPos > rowInfo[r+1].height )
-            rowInfo[r+1].height = rowPos;
-
-        // 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 = rowInfo[ indx ].height + 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 (rowInfo[r+1].height<bRowPos)
-            rowInfo[r+1].height=bRowPos;
-
-        rowInfo[r].baseline=baseline;
-    }
-
-    if ( rowInfo[r+1].height < rowInfo[r].height )
-        rowInfo[r+1].height = rowInfo[r].height;
 }
 
 void RenderTable::layout()
 {
     KHTMLAssert( !layouted() );
     KHTMLAssert( minMaxKnown() );
+    KHTMLAssert( !needSectionRecalc );
 
     //kdDebug( 6040 ) << renderName() << "(Table)"<< this << " ::layout0() width=" << width() << ", layouted=" << layouted() << endl;
 
-    _lastParentWidth = containingBlockWidth();
-
     m_height = 0;
 
-    int oldWidth = m_width;
+    //int oldWidth = m_width;
     calcWidth();
-    if ( !colWidthKnown || oldWidth != m_width )
-	calcColWidth();
+
+    // the optimisation below doesn't work since the internal table
+    // layout could have changed.  we need to add a flag to the table
+    // layout that tells us if something has changed in the min max
+    // calculations to do it correctly.
+//     if ( oldWidth != m_width || columns.size() + 1 != columnPos.size() )
+    tableLayout->layout();
 
 #ifdef DEBUG_LAYOUT
     kdDebug( 6040 ) << renderName() << "(Table)::layout1() width=" << width() << ", marginLeft=" << marginLeft() << " marginRight=" << marginRight() << endl;
 #endif
 
-
     setCellWidths();
 
-    // ### collapse caption margin, left, right
-    if(tCaption && tCaption->style()->captionSide() != CAPBOTTOM)
-    {
-        tCaption->setPos(m_height, tCaption->marginLeft());
-	if ( !tCaption->layouted() )
-	    tCaption->layout();
-        m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom();
-    }
-
     // layout child objects
+    int calculatedHeight = 0;
+
     RenderObject *child = firstChild();
     while( child ) {
-        if ( child != tCaption && !child->layouted() && !(child->element() && child->element()->id() == ID_FORM))
-            child->layout();
-        child = child->nextSibling();
+	if ( !child->layouted() )
+	    child->layout();
+	if ( child->isTableSection() ) {
+	    static_cast<RenderTableSection *>(child)->calcRowHeight();
+	    calculatedHeight += static_cast<RenderTableSection *>(child)->layoutRows( 0 );
+	}
+	child = child->nextSibling();
     }
 
-    // layout rows
-    layoutRows(m_height);
-
-    m_height += rowInfo[totalRows].height;
-    m_height += borderBottom();
-
-    if(tCaption && tCaption->style()->captionSide()==CAPBOTTOM)
-    {
+    // ### collapse caption margin
+    if(tCaption && tCaption->style()->captionSide() != CAPBOTTOM) {
         tCaption->setPos(tCaption->marginLeft(), m_height);
-	if ( !tCaption->layouted() )
-	    tCaption->layout();
         m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom();
     }
 
-    //kdDebug(0) << "table height: " << m_height << endl;
-
-    calcHeight();
-
-    //kdDebug(0) << "table height: " << m_height << endl;
-
-    // table can be containing block of positioned elements.
-    // ### only pass true if width or height changed.
-    layoutSpecialObjects( true );
-
-    setLayouted();
-
-}
-
-
-void RenderTable::layoutRows(int yoff)
-{
-    int rHeight;
-    int indx, rindx;
-
-    for ( unsigned int r = 0; r < totalRows; r++ ) {
-        calcRowHeight(r);
-    }
+    m_height += borderTop();
 
     // html tables with percent height are relative to view
     Length h = style()->height();
@@ -1487,146 +309,59 @@ void RenderTable::layoutRows(int yoff)
             }
         }
     }
-    
-    bool tableGrew = false;
-    if (th && totalRows)
-    {
-        th-=(totalRows+1)*spacing;
-        int dh = th-rowInfo[totalRows].height;
-        if (dh>0)
-        {
-            // There is room to grow.  Distribute the space among the rows
-            // by weighting according to their calculated heights,
-            // unless there are rows that have percentage
-            // heights.  In that case, only the rows with percentage heights
-            // get the space, and the weight is distributed after computing
-            // a normalized flex. -dwh
-            tableGrew = true;
-            int totalPercentage = 0;
-            for ( unsigned int r = 0; r < totalRows; r++ )
-                totalPercentage += rowInfo[r+1].percentage;
-                       
-            int tot=rowInfo[totalRows].height;
-            int add=0;
-            int prev=rowInfo[0].height;
-            for ( unsigned int r = 0; r < totalRows; r++ )
-            {
-                //weight with the original height
-                if (totalPercentage) {
-                    if (rowInfo[r+1].percentage)
-                        add += (rowInfo[r+1].percentage/totalPercentage)*dh;
-                }
-                else if (tot)
-                    add+=dh*(rowInfo[r+1].height-prev)/tot;
-                prev=rowInfo[r+1].height;
-                rowInfo[r+1].height+=add;
-            }
-            
-            int remaining = th - (rowInfo[totalRows].height + add);
-            if (remaining > 0 && totalRows > 0)
-                // Just give the space to the last row.
-                rowInfo[totalRows-1].height += remaining;
-            
-            rowInfo[totalRows].height=th;
+
+    // layout rows
+    if ( th > calculatedHeight ) {
+	// we have to redistribute that height to get the constraint correctly
+	// just force the first body to the height needed
+	// ### FIXME This should take height constraints on all table sections into account and distribute
+	// accordingly. For now this should be good enough
+        if (firstBody) {
+            firstBody->calcRowHeight();
+            firstBody->layoutRows( th - calculatedHeight );
         }
     }
+    int bl = borderLeft();
 
+    // position the table sections
+    if ( head ) {
+	head->setPos(bl, m_height);
+	m_height += head->height();
+    }
+    RenderObject *body = firstBody;
+    while ( body ) {
+	if ( body != head && body != foot && body->isTableSection() ) {
+	    body->setPos(bl, m_height);
+	    m_height += body->height();
+	}
+	body = body->nextSibling();
+    }
+    if ( foot ) {
+	foot->setPos(bl, m_height);
+	m_height += foot->height();
+    }
 
-    for ( unsigned int r = 0; r < totalRows; r++ )
-    {
-        for ( unsigned int c = 0; c < totalCols; c++ )
-        {
-            RenderTableCell *cell = cells[r][c];
-            if (!cell)
-                continue;
-            if ( c < totalCols - 1 && cell == cells[r][c+1] )
-                continue;
-            if ( r < totalRows - 1 && cell == cells[r+1][c] )
-                continue;
 
-            if ( ( indx = c-cell->colSpan()+1 ) < 0 )
-                indx = 0;
+    m_height += borderBottom();
 
-            if ( ( rindx = r-cell->rowSpan()+1 ) < 0 )
-                rindx = 0;
+    if(tCaption && tCaption->style()->captionSide()==CAPBOTTOM) {
+        tCaption->setPos(tCaption->marginLeft(), m_height);
+        m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom();
+    }
 
-            //kdDebug( 6040 ) << "setting position " << r << "/" << indx << "-" << c << ": " << //columnPos[indx] + padding << "/" << rowHeights[rindx] << " " << endl;
-            rHeight = rowInfo[r+1].height - rowInfo[rindx].height -
-                spacing;
+    //kdDebug(0) << "table height: " << m_height << endl;
 
-            cell->setRowHeight(rHeight);
-            bool cellChildrenFlex = false;
-            if (rowInfo[r+1].percentage) {
-	        // Force the child to lay itself out again.
-	        // This will cause, e.g., textareas to grow to
-	        // fill the area.  XXX <div>s and blocks still don't
-	        // work right. -dwh
-                cell->setCellPercentageHeight(rHeight);
-                RenderObject* o = cell->firstChild();
-                while (o) {
-                    if (o->style()->height().isPercent())
-                        o->setLayouted(false);
-                    o = o->nextSibling();
-                }
-                if (!cell->layouted()) {
-                    cellChildrenFlex = true;
-                    cell->layout();
-                }
-            }
-    
-            if (cellChildrenFlex) {
-                // Alignment within a cell is based off the calculated
-                // height, which becomes irrelevant once the cell has
-                // been resized based off its percentage. -dwh
-                cell->setCellTopExtra(0);
-                cell->setCellBottomExtra(0);
-            }
-            else {
-                EVerticalAlign va = cell->style()->verticalAlign();
-                int te=0;
-                switch (va)
-                {
-                case SUB:
-                case SUPER:
-                case TEXT_TOP:
-                case TEXT_BOTTOM:
-                case BASELINE:
-                    te = getBaseline(r) - cell->baselinePosition() ;
-                    break;
-                case TOP:
-                    te = 0;
-                    break;
-                case MIDDLE:
-                    te = (rHeight - cell->height())/2;
-                    break;
-                case BOTTOM:
-                    te = rHeight - cell->height();
-                    break;
-                default:
-                    break;
-                }
-    #ifdef DEBUG_LAYOUT
-                kdDebug( 6040 ) << "CELL te=" << te << ", be=" << rHeight - cell->height() - te << ", rHeight=" << rHeight << ", valign=" << va << endl;
-    #endif
-                cell->setCellTopExtra( te );
-                cell->setCellBottomExtra( rHeight - cell->height() - te);
-            }
-            
-            if (style()->direction()==RTL)
-            {
-                cell->setPos( columnPos[(int)totalCols]
-                    - columnPos[(int)(indx+cell->colSpan())] + borderLeft(),
-                    rowInfo[rindx].height+yoff );
-            }
-            else
-                cell->setPos( columnPos[indx] + borderLeft(), rowInfo[rindx].height+yoff );
+    calcHeight();
 
-            // ###
-            // cell->setHeight(cellHeight);
-        }
-    }
-}
+    //kdDebug(0) << "table height: " << m_height << endl;
 
+    // table can be containing block of positioned elements.
+    // ### only pass true if width or height changed.
+    layoutSpecialObjects( true );
+
+    setLayouted();
+
+}
 
 void RenderTable::setCellWidths()
 {
@@ -1634,32 +369,20 @@ void RenderTable::setCellWidths()
     kdDebug( 6040 ) << renderName() << "(Table, this=0x" << this << ")::setCellWidths()" << endl;
 #endif
 
-
-    int indx;
-    FOR_EACH_CELL( r, c, cell)
-        {
-            if ( ( indx = c-cell->colSpan()+1) < 0 )
-                indx = 0;
-            int w = columnPos[c+1] - columnPos[ indx ] - spacing; //- padding*2;
-
-#ifdef TABLE_DEBUG
-            kdDebug( 6040 ) << "0x" << this << ": setting width " << r << "/" << indx << "-" << c << " (0x" << cell << "): " << w << " " << endl;
-#endif
-	    int oldWidth = cell->width();
-            cell->setWidth( w );
-            if ( w != oldWidth )
-                cell->setLayouted(false);
-        }
-    END_FOR_EACH
-
+    RenderObject *child = firstChild();
+    while( child ) {
+	if ( child->isTableSection() )
+	    static_cast<RenderTableSection *>(child)->setCellWidths();
+	child = child->nextSibling();
+    }
 }
 
-void RenderTable::paint(QPainter *p, int _x, int _y,
-                        int _w, int _h, int _tx, int _ty, int paintPhase)
+void RenderTable::paint( QPainter *p, int _x, int _y,
+                                  int _w, int _h, int _tx, int _ty, int paintPhase)
 {
-
-//     if(!layouted()) return;
-
+    if (!layouted())
+        return;
+        
     _tx += xPos();
     _ty += yPos();
 
@@ -1673,64 +396,17 @@ void RenderTable::paint(QPainter *p, int _x, int _y,
     }
 
 #ifdef TABLE_PRINT
-     kdDebug( 6040 ) << "RenderTable::paint(2) " << _tx << "/" << _ty << " (" << _x << "/" << _y << ")" << endl;
+    kdDebug( 6040 ) << "RenderTable::paint(2) " << _tx << "/" << _ty << " (" << _y << "/" << _h << ")" << endl;
 #endif
-    // the case below happens during parsing
-    // when we have a new table that never got layouted. Don't paint it.
-    if ( totalRows == 1 && rowInfo[1].height == 0 )
-        return;
 
-    if (paintPhase == BACKGROUND_PHASE && style()->visibility() == VISIBLE)
-         paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
-
-    int topextra = 0;
-
-    if ( tCaption ) {
-        tCaption->paint( p, _x, _y, _w, _h, _tx, _ty, paintPhase );
-        if (tCaption->style()->captionSide() != CAPBOTTOM)
-            topextra = - borderTopExtra();
-    }
-
-    // check which rows and cols are visible and only paint these
-    // ### fixme: could use a binary search here
-    unsigned int startrow = 0;
-    unsigned int endrow = totalRows;
-    for ( ; startrow < totalRows; startrow++ ) {
-	if ( _ty + topextra + rowInfo[startrow+1].height > _y )
-	    break;
-    }
-    for ( ; endrow > 0; endrow-- ) {
-	if ( _ty + topextra + rowInfo[endrow-1].height < _y + _h )
-	    break;
-    }
-    unsigned int startcol = 0;
-    unsigned int endcol = totalCols;
-    if ( style()->direction() == LTR ) {
-    for ( ; startcol < totalCols; startcol++ ) {
-	if ( _tx + columnPos[startcol+1] > _x )
-	    break;
-    }
-    for ( ; endcol > 0; endcol-- ) {
-	if ( _tx + columnPos[endcol-1] < _x + _w )
-	    break;
-    }
-    }
+    if(paintPhase == BACKGROUND_PHASE && style()->visibility() == VISIBLE)
+        paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
 
-    // draw the cells
-    for ( unsigned int r = startrow; r < endrow; r++ ) {
-        for ( unsigned int c = startcol; c < endcol; c++ ) {
-            RenderTableCell *cell = cells[r][c];
-            if (!cell)
-                continue;
-            if ( (c < endcol - 1) && (cell == cells[r][c+1]) )
-                continue;
-            if ( (r < endrow - 1) && (cells[r+1][c] == cell) )
-                continue;
-#ifdef DEBUG_LAYOUT
-	    kdDebug( 6040 ) << "painting cell " << r << "/" << c << endl;
-#endif
-	    cell->paint( p, _x, _y, _w, _h, _tx, _ty, paintPhase);
-	}
+    RenderObject *child = firstChild();
+    while( child ) {
+	if ( child->isTableSection() || child == tCaption )
+	    child->paint( p, _x, _y, _w, _h, _tx, _ty, paintPhase );
+	child = child->nextSibling();
     }
 
 #ifdef BOX_DEBUG
@@ -1742,22 +418,21 @@ void RenderTable::calcMinMaxWidth()
 {
     KHTMLAssert( !minMaxKnown() );
 
-    if ( needsCellsRecalc )
-       recalcCells();
+    if ( needSectionRecalc )
+	recalcSections();
+
 #ifdef DEBUG_LAYOUT
     kdDebug( 6040 ) << renderName() << "(Table " << this << ")::calcMinMaxWidth()" <<  endl;
 #endif
 
-    /*
-     * Calculate min and max width for every column,
-     * Max width for percent cols are still not accurate, but as they don't
-     * influence the total max width of the table we don't care.
-     */
-     calcColMinMax();
+    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;
+    kdDebug( 6040 ) << renderName() << " END: (Table " << this << ")::calcMinMaxWidth() min = " << m_minWidth << " max = " << m_maxWidth <<  endl;
 #endif
 }
 
@@ -1785,93 +460,168 @@ int RenderTable::borderBottomExtra()
         return 0;
 }
 
-void RenderTable::setNeedsCellsRecalc()
-{
-    needsCellsRecalc = true;
-    setMinMaxKnown(false);
-    setLayouted(false);
-}
 
-void RenderTable::recalcCells()
+void RenderTable::splitColumn( int pos, int firstSpan )
 {
-    needsCellsRecalc = false;
+    // 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;
 
-    _oldColElem = 0;
-    m_maxWidth = 0;
-
-    row = 0;
-    col = 0;
-
-    maxColSpan = 0;
-
-    _currentCol=0;
-
-    _lastParentWidth = 0;
+    // 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 );
+    setMinMaxKnown( false );
+    setLayouted( false );
+}
 
-    columnPos.resize( 0 );
-    columnPos.resize( 1 );
-    colMaxWidth.resize( 0 );
-    colMaxWidth.resize( 1 );
-    colMinWidth.resize( 0 );
-    colMinWidth.resize( 1 );
-    colValue.resize(0);
-    colValue.resize(1);
-    colType.resize(0);
-    colType.resize(1);
-    actColWidth.resize(0);
-    actColWidth.resize(1);
-    columnPos.fill( 0 );
-    colMaxWidth.fill( 0 );
-    colMinWidth.fill( 0 );
-    colValue.fill(0);
-    colType.fill(Variable);
-    actColWidth.fill(0);
+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 );
 
-    columnPos[0] = spacing;
+    // 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++;
+	    }
 
-    for (unsigned int r = 0; r < allocRows; r++)
-    {
-	delete[] cells[r];
+	}
+	child = child->nextSibling();
     }
-    delete[] cells;
-
-    totalCols = 0;   // this should be expanded to the maximum number of cols
-                     // by the first row parsed
-    totalRows = 0;
-    allocRows = 5;   // allocate five rows initially
+    columnPos.resize( numEffCols()+1 );
+    setMinMaxKnown( false );
+    setLayouted( false );
+}
 
-    cells = new RenderTableCell ** [allocRows];
+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;
+	    }
 
-    for ( unsigned int r = 0; r < allocRows; r++ )
-    {
-        cells[r] = new RenderTableCell * [totalCols];
-        memset( cells[r], 0, totalCols * sizeof( RenderTableCell * ));
+	    RenderObject *next = child->firstChild();
+	    if ( !next )
+		next = child->nextSibling();
+	    if ( !next && child->parent()->isTableCol() )
+		next = child->parent()->nextSibling();
+	    child = next;
+	} else
+	    break;
     }
+    return 0;
+}
 
-    for (RenderObject *s = m_first; s; s = s->nextSibling()) {
-	if (s->isTableSection()) {
-	    for (RenderObject *r = static_cast<RenderTableSection*>(s)->firstChild(); r; r = r->nextSibling()) {
-		if (r->isTableRow()) {
-		    startRow();
-		    for (RenderObject *c = static_cast<RenderTableRow*>(r)->firstChild(); c; c = c->nextSibling()) {
-			if (c->isTableCell())
-			    addCell(static_cast<RenderTableCell*>(c));
-		    }
-		    closeRow();
-		}
-	    }
+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<RenderFlow*>(child);
+                tCaption->setLayouted(false);
+            }
+	    break;
+	case TABLE_COLUMN:
+	case TABLE_COLUMN_GROUP:
+	    has_col_elems = true;
+	    return;
+	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;
+    setLayouted( false );
+}
 
-    recalcColInfos();
+RenderObject* RenderTable::removeChildNode(RenderObject* child)
+{
+    setNeedSectionRecalc();
+    return RenderContainer::removeChildNode( child );
 }
 
+
 #ifndef NDEBUG
 void RenderTable::dump(QTextStream *stream, QString ind) const
 {
-    *stream << " totalCols=" << totalCols;
-    *stream << " totalRows=" << totalRows;
-
     if (tCaption)
 	*stream << " tCaption";
     if (head)
@@ -1879,14 +629,10 @@ void RenderTable::dump(QTextStream *stream, QString ind) const
     if (foot)
 	*stream << " foot";
 
-    if (collapseBorders)
-	*stream << " collapseBorders";
-
-// ###    RenderTableCell ***cells;
-// ###    QPtrVector<ColInfoLine> colInfos;
-// ###    Frame frame;
-// ###    Rules rules;
-// ###    RenderTableCol *_oldColElem;
+    *stream << endl << ind << "cspans:";
+    for ( unsigned int i = 0; i < columns.size(); i++ )
+	*stream << " " << columns[i].span;
+    *stream << endl << ind;
 
     RenderFlow::dump(stream,ind);
 }
@@ -1895,19 +641,39 @@ void RenderTable::dump(QTextStream *stream, QString ind) const
 // --------------------------------------------------------------------------
 
 RenderTableSection::RenderTableSection(DOM::NodeImpl* node)
-    : RenderContainer(node)
+    : RenderBox(node)
 {
     // init RenderObject attributes
     setInline(false);   // our object is not Inline
-    nrows = 0;
+    cCol = 0;
+    cRow = -1;
+    needCellRecalc = false;
 }
 
 RenderTableSection::~RenderTableSection()
 {
+    clearGrid();
+}
+
+void RenderTableSection::detach(RenderArena* arena)
+{
     // recalc cell info because RenderTable has unguarded pointers
     // stored that point to this RenderTableSection.
-    if (table)
-        table->setNeedsCellsRecalc();
+    if (table())
+        table()->setNeedSectionRecalc();
+
+    RenderBox::detach(arena);
+}
+
+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)
@@ -1924,6 +690,7 @@ void RenderTableSection::addChild(RenderObject *child, RenderObject *beforeChild
     }
     
     if ( !child->isTableRow() ) {
+
         if( !beforeChild )
             beforeChild = lastChild();
 
@@ -1937,11 +704,11 @@ void RenderTableSection::addChild(RenderObject *child, RenderObject *beforeChild
 		lastBox->addChild( child, beforeChild );
 		return;
 	    } else {
-		kdDebug( 6040 ) << "creating anonymous table row" << endl;
+		//kdDebug( 6040 ) << "creating anonymous table row" << endl;
 		row = new (renderArena()) RenderTableRow(0 /* anonymous table */);
 		RenderStyle *newStyle = new RenderStyle();
 		newStyle->inheritFrom(style());
-		newStyle->setDisplay(TABLE_ROW);
+		newStyle->setDisplay( TABLE_ROW );
 		row->setStyle(newStyle);
 		row->setIsAnonymousBox(true);
 		addChild(row, beforeChild);
@@ -1954,56 +721,556 @@ void RenderTableSection::addChild(RenderObject *child, RenderObject *beforeChild
     }
 
     if (beforeChild)
-	table->setNeedsCellsRecalc();
+	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();
+    }
+
 
-    table->startRow();
-    child->setTable(table);
     RenderContainer::addChild(child,beforeChild);
 }
 
-#ifndef NDEBUG
-void RenderTableSection::dump(QTextStream *stream, QString ind) const
+void RenderTableSection::ensureRows( int numRows )
 {
-    *stream << " nrows=" << nrows;
+    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();
+	}
+    }
 
-    RenderContainer::dump(stream,ind);
 }
+
+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;
+	    }
+	}
+    }
 
-RenderTableRow::RenderTableRow(DOM::NodeImpl* node)
-    : RenderContainer(node)
+    // 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()
 {
-    // init RenderObject attributes
-    setInline(false);   // our object is not Inline
+#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()->cellSpacing();
+#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->setLayouted(false);
+		cell->setWidth( w );
+	    }
+	}
+    }
+}
+
+
+void RenderTableSection::calcRowHeight()
+{
+    int indx;
+    RenderTableCell *cell;
+
+    int totalRows = grid.size();
+    int spacing = table()->cellSpacing();
+
+    rowPos.resize( totalRows + 1 );
+    rowPos[0] =  spacing + borderTop();
+
+    for ( int r = 0; r < totalRows; r++ ) {
+	rowPos[r+1] = 0;
 
-    rIndex = -1;
-    ncols = 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 + table()->cellSpacing();
+
+	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;
+
+	    ch = cell->style()->height().width(0);
+	    if ( cell->height() > ch)
+		ch = cell->height();
+
+	    pos = rowPos[ indx ] + ch + table()->cellSpacing();
+
+	    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  + table()->cellSpacing() ; // + 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] );
+    }
 }
 
-RenderTableRow::~RenderTableRow()
+int RenderTableSection::layoutRows( int toAdd )
 {
-    if (table)
-        table->setNeedsCellsRecalc();
+    int rHeight;
+    int rindx;
+    int totalRows = grid.size();
+    int spacing = table()->cellSpacing();
+
+    if (toAdd && totalRows && rowPos[totalRows]) {
+
+	int totalHeight = rowPos[totalRows] + toAdd;
+// 	qDebug("layoutRows: totalHeight = %d",  totalHeight );
+
+        int dh = totalHeight-rowPos[totalRows];
+	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 = QMIN( dh, (totalHeight * grid[r].height.value / 100)-rh );
+		    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;
+	    for ( int r = 0; r < totalRows; r++ ) {
+		if ( numVariable > 0 && grid[r].height.type == Variable ) {
+		    int toAdd = dh/numVariable;
+		    add += toAdd;
+		    dh -= toAdd;
+		}
+                rowPos[r+1] += add;
+	    }
+	}
+        if (dh>0) {
+	    // if some left overs, distribute equally.
+            int tot=rowPos[totalRows];
+            int add=0;
+            int prev=rowPos[0];
+            for ( int r = 0; r < totalRows; r++ ) {
+                //weight with the original height
+                add+=dh*(rowPos[r+1]-prev)/tot;
+                prev=rowPos[r+1];
+                rowPos[r+1]+=add;
+            }
+        }
+    }
+
+    int leftOffset = borderLeft() + spacing;
+
+    int nEffCols = table()->numEffCols();
+    for ( int r = 0; r < totalRows; r++ )
+    {
+	Row *row = grid[r].row;
+	int totalCols = row->size();
+        for ( int c = 0; c < nEffCols; c++ )
+        {
+            RenderTableCell *cell = cellAt(r, c);
+            if (!cell || cell == (RenderTableCell *)-1 )
+                continue;
+            if ( r < totalRows - 1 && cell == cellAt(r+1, c) )
+		continue;
+
+            if ( ( rindx = r-cell->rowSpan()+1 ) < 0 )
+                rindx = 0;
+
+            rHeight = rowPos[r+1] - rowPos[rindx] - spacing;
+            
+            // Force percent height children to lay themselves out again.
+            // This will cause, e.g., textareas to grow to
+            // fill the area.  FIXME: <div>s and blocks still don't
+            // work right.  We'll need to have an efficient way of
+            // invalidating all percent height objects in a render subtree.
+            // For now, we just handle immediate children. -dwh
+            bool cellChildrenFlex = false;
+            RenderObject* o = cell->firstChild();
+            while (o) {
+                if (o->style()->height().isPercent()) {
+                    o->setLayouted(false);
+                    cellChildrenFlex = true;
+                }
+                o = o->nextSibling();
+            }
+            if (cellChildrenFlex) {
+                cell->setCellPercentageHeight(rHeight);
+                cell->layout();
+           
+                // Alignment within a cell is based off the calculated
+                // height, which becomes irrelevant once the cell has
+                // been resized based off its percentage. -dwh
+                cell->setCellTopExtra(0);
+                cell->setCellBottomExtra(0);
+            }
+            else {
+#ifdef DEBUG_LAYOUT
+            kdDebug( 6040 ) << "setting position " << r << "/" << c << ": "
+			    << table()->columnPos[c] /*+ padding */ << "/" << rowPos[rindx] << " height=" << rHeight<< endl;
+#endif
+
+            EVerticalAlign va = cell->style()->verticalAlign();
+            int te=0;
+            switch (va)
+            {
+            case SUB:
+            case SUPER:
+            case TEXT_TOP:
+            case TEXT_BOTTOM:
+            case BASELINE:
+		te = getBaseline(r) - cell->baselinePosition() ;
+                break;
+            case TOP:
+                te = 0;
+                break;
+            case MIDDLE:
+                te = (rHeight - cell->height())/2;
+                break;
+            case BOTTOM:
+                te = rHeight - cell->height();
+                break;
+            default:
+                break;
+            }
+#ifdef DEBUG_LAYOUT
+	    //            kdDebug( 6040 ) << "CELL " << cell << " te=" << te << ", be=" << rHeight - cell->height() - te << ", rHeight=" << rHeight << ", valign=" << va << endl;
+#endif
+            cell->setCellTopExtra( te );
+            cell->setCellBottomExtra( rHeight - cell->height() - te);
+            }
+            
+            if (style()->direction()==RTL) {
+                cell->setPos(
+		    table()->columnPos[(int)totalCols] -
+		    table()->columnPos[table()->colToEffCol(cell->col()+cell->colSpan())] +
+		    leftOffset,
+                    rowPos[rindx] );
+            } else {
+                cell->setPos( table()->columnPos[c] + leftOffset, rowPos[rindx] );
+	    }
+        }
+    }
+
+    m_height = rowPos[totalRows];
+    return m_height;
 }
 
 
-long RenderTableRow::rowIndex() const
+void RenderTableSection::paint( QPainter *p, int x, int y, int w, int h,
+				int tx, int ty, int paintPhase)
 {
-    // ###
-    return 0;
+    unsigned int totalRows = grid.size();
+    unsigned int totalCols = table()->columns.size();
+
+    tx += m_x;
+    ty += m_y;
+
+    // check which rows and cols are visible and only paint these
+    // ### fixme: could use a binary search here
+    unsigned int startrow = 0;
+    unsigned int endrow = totalRows;
+    for ( ; startrow < totalRows; startrow++ ) {
+	if ( ty + rowPos[startrow+1] > y )
+	    break;
+    }
+    for ( ; endrow > 0; endrow-- ) {
+	if ( ty + rowPos[endrow-1] < y + h )
+	    break;
+    }
+    unsigned int startcol = 0;
+    unsigned int endcol = totalCols;
+    if ( style()->direction() == LTR ) {
+	for ( ; startcol < totalCols; startcol++ ) {
+	    if ( tx + table()->columnPos[startcol+1] > x )
+		break;
+	}
+	for ( ; endcol > 0; endcol-- ) {
+	    if ( tx + table()->columnPos[endcol-1] < x + w )
+		break;
+	}
+    }
+    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 )
+		c--;
+	    for ( ; c < endcol; c++ ) {
+		RenderTableCell *cell = cellAt(r, c);
+		if (!cell || cell == (RenderTableCell *)-1 )
+		    continue;
+		if ( (r < endrow - 1) && (cellAt(r+1, c) == cell) )
+		    continue;
+
+#ifdef TABLE_PRINT
+		kdDebug( 6040 ) << "painting cell " << r << "/" << c << endl;
+#endif
+		cell->paint( p, x, y, w, h, tx, ty, paintPhase);
+	    }
+	}
+    }
+}
+
+void RenderTableSection::recalcCells()
+{
+    cCol = 0;
+    cRow = -1;
+    clearGrid();
+    grid.resize( 0 );
+
+    RenderObject *row = firstChild();
+    while ( row ) {
+	cRow++;
+	cCol = 0;
+	ensureRows( cRow+1 );
+	RenderObject *cell = row->firstChild();
+	while ( cell ) {
+	    if ( cell->isTableCell() )
+		addCell( static_cast<RenderTableCell *>(cell) );
+	    cell = cell->nextSibling();
+	}
+	row = row->nextSibling();
+    }
+    needCellRecalc = false;
+    setLayouted( false );
 }
 
-void RenderTableRow::setRowIndex( long  )
+void RenderTableSection::clearGrid()
 {
-    // ###
+    int rows = grid.size();
+    while ( rows-- ) {
+	delete grid[rows].row;
+    }
 }
 
-void RenderTableRow::close()
+RenderObject* RenderTableSection::removeChildNode(RenderObject* child)
 {
-    table->closeRow();
-    RenderContainer::close();
+    setNeedCellRecalc();
+    return RenderContainer::removeChildNode( child );
+}
+
+#ifndef NDEBUG
+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() << ") ";
+	    else
+		*stream << cellAt( r, c ) << "null cell ";
+	}
+	*stream << endl << ind;
+    }
+    RenderContainer::dump(stream,ind);
+}
+#endif
+
+// -------------------------------------------------------------------------
+
+RenderTableRow::RenderTableRow(DOM::NodeImpl* node)
+    : RenderContainer(node)
+{
+    // init RenderObject attributes
+    setInline(false);   // our object is not Inline
+}
+
+void RenderTableRow::detach(RenderArena* arena)
+{
+    section()->setNeedCellRecalc();
+
+    RenderContainer::detach(arena);
+}
+
+void RenderTableRow::setStyle(RenderStyle* style)
+{
+    style->setDisplay(TABLE_ROW);
+    RenderContainer::setStyle(style);
 }
 
 void RenderTableRow::addChild(RenderObject *child, RenderObject *beforeChild)
@@ -2012,36 +1279,28 @@ void RenderTableRow::addChild(RenderObject *child, RenderObject *beforeChild)
     kdDebug( 6040 ) << renderName() << "(TableRow)::addChild( " << child->renderName() << " )"  << ", " <<
                        (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;
 #endif
-    RenderTableCell *cell;
-
     if (child->element() && child->element()->id() == ID_FORM) {
         RenderContainer::addChild(child,beforeChild);
         return;
     }
 
+    RenderTableCell *cell;
+
     if ( !child->isTableCell() ) {
-        if ( !beforeChild )
-            beforeChild = lastChild();
-        RenderTableCell *cell;
-        if( beforeChild && beforeChild->isAnonymousBox() && beforeChild->isTableCell() )
-            cell = static_cast<RenderTableCell *>(beforeChild);
+	RenderObject *last = beforeChild;
+        if ( !last )
+            last = lastChild();
+        RenderTableCell *cell = 0;
+        if( last && last->isAnonymousBox() && last->isTableCell() )
+            cell = static_cast<RenderTableCell *>(last);
         else {
-	    RenderObject *lastBox = beforeChild;
-	    while ( lastBox && lastBox->parent()->isAnonymousBox() && !lastBox->isTableCell() )
-		lastBox = lastBox->parent();
-	    if ( lastBox && lastBox->isAnonymousBox() ) {
-		lastBox->addChild( child, beforeChild );
-		return;
-	    } else {
-//          kdDebug( 6040 ) << "creating anonymous table cell" << endl;
-		cell = new (renderArena()) RenderTableCell(0 /* anonymous object */);
-		RenderStyle *newStyle = new RenderStyle();
-		newStyle->inheritFrom(style());
-		newStyle->setDisplay(TABLE_CELL);
-		cell->setStyle(newStyle);
-		cell->setIsAnonymousBox(true);
-		addChild(cell, beforeChild);
-	    }
+	    cell = new (renderArena()) RenderTableCell(0 /* anonymous object */);
+	    RenderStyle *newStyle = new RenderStyle();
+	    newStyle->inheritFrom(style());
+	    newStyle->setDisplay( TABLE_CELL );
+	    cell->setStyle(newStyle);
+	    cell->setIsAnonymousBox(true);
+	    addChild(cell, beforeChild);
         }
         cell->addChild(child);
 	child->setLayouted( false );
@@ -2050,28 +1309,25 @@ void RenderTableRow::addChild(RenderObject *child, RenderObject *beforeChild)
     } else
         cell = static_cast<RenderTableCell *>(child);
 
-    cell->setTable(table);
-    cell->setRowImpl(this);
-    table->addCell(cell);  // ### may not work for beforeChild != 0
+    static_cast<RenderTableSection *>(parent())->addCell( cell );
 
     RenderContainer::addChild(cell,beforeChild);
 
-    if (beforeChild || nextSibling())
-	table->setNeedsCellsRecalc();
-
+    if ( ( beforeChild || nextSibling()) && section() )
+	section()->setNeedCellRecalc();
 }
 
-void RenderTableRow::repaint(bool immediate)
+RenderObject* RenderTableRow::removeChildNode(RenderObject* child)
 {
-    if ( table ) table->repaint(immediate);
+// RenderTableCell detach should do it
+//     if ( section() )
+// 	section()->setNeedCellRecalc();
+    return RenderContainer::removeChildNode( child );
 }
 
 #ifndef NDEBUG
 void RenderTableRow::dump(QTextStream *stream, QString ind) const
 {
-    *stream << " rIndex = " << rIndex;
-    *stream << " ncols = " << ncols;
-
     RenderContainer::dump(stream,ind);
 }
 #endif
@@ -2083,14 +1339,14 @@ void RenderTableRow::layout()
 
     RenderObject *child = firstChild();
     while( child ) {
-        if (child->isTableCell() && !child->layouted() ) {
-            RenderTableCell *cell = static_cast<RenderTableCell *>(child);
-            cell->calcVerticalMargins();
-            cell->layout();
-            cell->setCellTopExtra(0);
-            cell->setCellBottomExtra(0);
-        }
-        child = child->nextSibling();
+	if ( child->isTableCell() && !child->layouted() ) {
+	    RenderTableCell *cell = static_cast<RenderTableCell *>(child);
+	    cell->calcVerticalMargins();
+	    cell->layout();
+	    cell->setCellTopExtra(0);
+	    cell->setCellBottomExtra(0);
+	}
+	child = child->nextSibling();
     }
     setLayouted();
 }
@@ -2103,20 +1359,18 @@ RenderTableCell::RenderTableCell(DOM::NodeImpl* _node)
   _col = -1;
   _row = -1;
   updateFromElement();
-  _id = 0;
-  rowHeight = 0;
-  cellPercentageHeight = 0;
-  m_table = 0;
-  rowimpl = 0;
   setShouldPaintBackgroundOrBorder(true);
   _topExtra = 0;
   _bottomExtra = 0;
+  m_percentageHeight = 0;
 }
 
-RenderTableCell::~RenderTableCell()
+void RenderTableCell::detach(RenderArena* arena)
 {
-    if (m_table)
-        m_table->setNeedsCellsRecalc();
+    if (parent() && section())
+        section()->setNeedCellRecalc();
+
+    RenderFlow::detach(arena);
 }
 
 void RenderTableCell::updateFromElement()
@@ -2126,13 +1380,21 @@ void RenderTableCell::updateFromElement()
       DOM::HTMLTableCellElementImpl *tc = static_cast<DOM::HTMLTableCellElementImpl *>(node);
       cSpan = tc->colSpan();
       rSpan = tc->rowSpan();
-      nWrap = tc->noWrap();
   } else {
       cSpan = rSpan = 1;
-      nWrap = false;
   }
 }
 
+int RenderTableCell::getCellPercentageHeight() const
+{
+    return m_percentageHeight;
+}
+
+void RenderTableCell::setCellPercentageHeight(int h)
+{
+    m_percentageHeight = h;
+}
+    
 void RenderTableCell::calcMinMaxWidth()
 {
     KHTMLAssert( !minMaxKnown() );
@@ -2140,30 +1402,8 @@ void RenderTableCell::calcMinMaxWidth()
     kdDebug( 6040 ) << renderName() << "(TableCell)::calcMinMaxWidth() known=" << minMaxKnown() << endl;
 #endif
 
-    //if(minMaxKnown()) return;
-
-    int oldMin = m_minWidth;
-    int oldMax = m_maxWidth;
-
     RenderFlow::calcMinMaxWidth();
-
-    // NOWRAP Should apply even in cases where the width is fixed.  Consider the following 
-    // test case.
-    // <table border="1">
-    // <tr>
-    // <td width="175">Check this text out. It shouldn't shrink below 300px.</td>
-    // <td width="100%"></td>
-    // </tr>
-    // <tr><td width="300" nowrap></tr>
-    // </table>
-    // The width of the cell should not be allowed to fall below the max width of the column when
-    // nowrap is enabled on any cell in the column.  - dwh
-    if(nWrap)
-        m_minWidth = m_maxWidth;
-
-    if (m_minWidth!=oldMin || m_maxWidth!=oldMax) {
-        m_table->addColInfo(this);
-    }
+    
     setMinMaxKnown();
 }
 
@@ -2188,41 +1428,6 @@ void RenderTableCell::close()
 #endif
 }
 
-int RenderTableCell::paddingTop() const
-{
-    if (style()->hasPadding())
-        return RenderFlow::paddingTop();
-    if (m_table && m_table->cellPadding() != -1)
-        return m_table->cellPadding();
-    return 0;
-}
-
-int RenderTableCell::paddingBottom() const
-{
-    if (style()->hasPadding())
-        return RenderFlow::paddingBottom();
-    if (m_table && m_table->cellPadding() != -1)
-        return m_table->cellPadding();
-    return 0;
-}
-
-int RenderTableCell::paddingLeft() const
-{
-    if (style()->hasPadding())
-        return RenderFlow::paddingLeft();
-    if (m_table && m_table->cellPadding() != -1)
-        return m_table->cellPadding();
-    return 0;
-}
-
-int RenderTableCell::paddingRight() const
-{
-    if (style()->hasPadding())
-        return RenderFlow::paddingRight();
-    if (m_table && m_table->cellPadding() != -1)
-        return m_table->cellPadding();
-    return 0;
-}
 
 void RenderTableCell::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
 {
@@ -2241,10 +1446,11 @@ bool RenderTableCell::absolutePosition(int &xPos, int &yPos, bool f)
 short RenderTableCell::baselinePosition( bool ) const
 {
     RenderObject *o = firstChild();
-    int offset = paddingTop();
+    int offset = paddingTop() + borderTop();
     if ( !o ) return offset;
     while ( o->firstChild() ) {
-	offset += paddingTop() + borderTop();
+	if ( !o->isInline() )
+	    offset += o->paddingTop() + o->borderTop();
 	o = o->firstChild();
     }
     offset += o->baselinePosition( true );
@@ -2254,8 +1460,19 @@ short RenderTableCell::baselinePosition( bool ) const
 
 void RenderTableCell::setStyle( RenderStyle *style )
 {
+    style->setDisplay(TABLE_CELL);
     RenderFlow::setStyle( style );
     setShouldPaintBackgroundOrBorder(true);
+    
+    if (style->whiteSpace() == KONQ_NOWRAP) {
+        // Figure out if we are really nowrapping or if we should just
+        // use normal instead.  If the width of the cell is fixed, then
+        // we don't actually use NOWRAP. 
+        if (style->width().isFixed())
+            style->setWhiteSpace(NORMAL);
+        else
+            style->setWhiteSpace(NOWRAP);
+    }
 }
 
 #ifdef BOX_DEBUG
@@ -2270,15 +1487,14 @@ static void outlineBox(QPainter *p, int _tx, int _ty, int w, int h)
 #endif
 
 void RenderTableCell::paint(QPainter *p, int _x, int _y,
-                            int _w, int _h, int _tx, int _ty, int paintPhase)
+                                       int _w, int _h, int _tx, int _ty, int paintPhase)
 {
 
 #ifdef TABLE_PRINT
-    kdDebug( 6040 ) << renderName() << "(RenderTableCell)::paint() w/h = (" << width() << "/" << height() << ")" << endl;
+    kdDebug( 6040 ) << renderName() << "(RenderTableCell)::paint() w/h = (" << width() << "/" << height() << ")" << " _y/_h=" << _y << "/" << _h << endl;
 #endif
 
-//    if (!layouted())
-//      return;
+    if (!layouted()) return;
 
     _tx += m_x;
     _ty += m_y + _topExtra;
@@ -2296,27 +1512,30 @@ void RenderTableCell::paint(QPainter *p, int _x, int _y,
 
 
 void RenderTableCell::paintBoxDecorations(QPainter *p,int, int _y,
-                                          int, int _h, int _tx, int _ty)
+                                       int, int _h, int _tx, int _ty)
 {
-    //kdDebug( 6040 ) << renderName() << "::paintBoxDecorations()" << endl;
-
     int w = width();
     int h = height() + borderTopExtra() + borderBottomExtra();
     _ty -= borderTopExtra();
 
-    int my = KMAX(_ty,_y);
-    int mh;
-    if (_ty<_y)
-        mh= KMAX(0,h-(_y-_ty));
-    else
-        mh = KMIN(_h,h);
-
     QColor c = style()->backgroundColor();
     if ( !c.isValid() && parent() ) // take from row
         c = parent()->style()->backgroundColor();
     if ( !c.isValid() && parent() && parent()->parent() ) // take from rowgroup
         c = parent()->parent()->style()->backgroundColor();
-    // ### col is missing...
+    if ( !c.isValid() ) {
+	// see if we have a col or colgroup for this
+	RenderTableCol *col = table()->colElement( _col );
+	if ( col ) {
+	    c = col->style()->backgroundColor();
+	    if ( !c.isValid() ) {
+		// try column group
+		RenderStyle *style = col->parent()->style();
+		if ( style->display() == TABLE_COLUMN_GROUP )
+		    c = style->backgroundColor();
+	    }
+	}
+    }
 
     // ### get offsets right in case the bgimage is inherited.
     CachedImage *bg = style()->backgroundImage();
@@ -2324,30 +1543,40 @@ void RenderTableCell::paintBoxDecorations(QPainter *p,int, int _y,
         bg = parent()->style()->backgroundImage();
     if ( !bg && parent() && parent()->parent() )
         bg = parent()->parent()->style()->backgroundImage();
+    if ( !bg ) {
+	// see if we have a col or colgroup for this
+	RenderTableCol *col = table()->colElement( _col );
+	if ( col ) {
+	    bg = col->style()->backgroundImage();
+	    if ( !bg ) {
+		// try column group
+		RenderStyle *style = col->parent()->style();
+		if ( style->display() == TABLE_COLUMN_GROUP )
+		    bg = style->backgroundImage();
+	    }
+	}
+    }
+
+    int my = QMAX(_ty,_y);
+    int end = QMIN( _y + _h,  _ty + h );
+    int mh = end - my;
 
     if ( bg || c.isValid() )
-        paintBackground(p, c, bg, my, mh, _tx, _ty, w, h);
+	paintBackground(p, c, bg, my, mh, _tx, _ty, w, h);
 
     if(style()->hasBorder())
         paintBorder(p, _tx, _ty, w, h, style());
 }
 
-void RenderTableCell::repaint(bool immediate)
-{
-    // XXXdwh WHY? This just causes way too much repainting!
-    //if ( m_table ) m_table->repaint(immediate);
-    return RenderFlow::repaint(immediate);
-}
 
 #ifndef NDEBUG
 void RenderTableCell::dump(QTextStream *stream, QString ind) const
 {
-    *stream << " _row=" << _row;
-    *stream << " _col=" << _col;
+    *stream << " row=" << _row;
+    *stream << " col=" << _col;
     *stream << " rSpan=" << rSpan;
     *stream << " cSpan=" << cSpan;
-    *stream << " _id=" << _id;
-    *stream << " nWrap=" << nWrap;
+//    *stream << " nWrap=" << nWrap;
 
     RenderFlow::dump(stream,ind);
 }
@@ -2363,13 +1592,6 @@ RenderTableCol::RenderTableCol(DOM::NodeImpl* node)
 
     _span = 1;
     updateFromElement();
-    _currentCol = 0;
-    _startCol = 0;
-    _id = 0;
-}
-
-RenderTableCol::~RenderTableCol()
-{
 }
 
 void RenderTableCol::updateFromElement()
@@ -2378,12 +1600,8 @@ void RenderTableCol::updateFromElement()
   if ( node && (node->id() == ID_COL || node->id() == ID_COLGROUP) ) {
       DOM::HTMLTableColElementImpl *tc = static_cast<DOM::HTMLTableColElementImpl *>(node);
       _span = tc->span();
-  } else {
-      if ( style()->display() == TABLE_COLUMN_GROUP )
-	  _span = 0;
-      else
-	  _span = 1;
-  }
+  } else
+      _span = ! ( style() && style()->display() == TABLE_COLUMN_GROUP );
 }
 
 void RenderTableCol::addChild(RenderObject *child, RenderObject *beforeChild)
@@ -2394,39 +1612,18 @@ void RenderTableCol::addChild(RenderObject *child, RenderObject *beforeChild)
 #endif
 
     if (child->style()->display() == TABLE_COLUMN)
-    {
         // these have to come before the table definition!
         RenderContainer::addChild(child,beforeChild);
-        RenderTableCol* colel = static_cast<RenderTableCol *>(child);
-        colel->setStartCol(_currentCol);
-//      kdDebug( 6040 ) << "_currentCol=" << _currentCol << endl;
-        table->addColInfo(colel);
-        _currentCol++;
-    }
 }
 
 #ifndef NDEBUG
 void RenderTableCol::dump(QTextStream *stream, QString ind) const
 {
     *stream << " _span=" << _span;
-    *stream << " _startCol=" << _startCol;
-    *stream << " _id=" << _id;
-
     RenderContainer::dump(stream,ind);
 }
 #endif
 
-// -------------------------------------------------------------------------
-
-RenderTableCaption::RenderTableCaption(DOM::NodeImpl* node)
-  : RenderFlow(node)
-{
-}
-
-RenderTableCaption::~RenderTableCaption()
-{
-}
-
 #undef TABLE_DEBUG
 #undef DEBUG_LAYOUT
 #undef BOX_DEBUG
diff --git a/WebCore/khtml/rendering/render_table.h b/WebCore/khtml/rendering/render_table.h
index fd8cf74..b057e3f 100644
--- a/WebCore/khtml/rendering/render_table.h
+++ b/WebCore/khtml/rendering/render_table.h
@@ -6,7 +6,6 @@
  *           (C) 1998 Waldo Bastian (bastian at kde.org)
  *           (C) 1999 Lars Knoll (knoll at kde.org)
  *           (C) 1999 Antti Koivisto (koivisto at kde.org)
- * Copyright (C) 2002 Apple Computer, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -23,6 +22,7 @@
  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  *
+ * $Id$
  */
 #ifndef RENDER_TABLE_H
 #define RENDER_TABLE_H
@@ -46,7 +46,7 @@ class RenderTableSection;
 class RenderTableRow;
 class RenderTableCell;
 class RenderTableCol;
-class RenderTableCaption;
+class TableLayout;
 
 class RenderTable : public RenderFlow
 {
@@ -81,49 +81,32 @@ public:
     virtual bool isRendered() const { return true; }
     virtual bool isTable() const { return true; }
 
-    int getColumnPos(int col)
+    int getColumnPos(int col) const
         { return columnPos[col]; }
-    int getColumnWidth(int col)
-        { if(!actColWidth.size() < col) return 0; return actColWidth[col]; }
 
-    int cellSpacing() { return spacing; }
+    int cellSpacing() const { return spacing; }
 
-    Rules getRules() { return rules; }
+    Rules getRules() const { return rules; }
 
-    QColor bgColor() { return style()->backgroundColor(); }
+    const QColor &bgColor() const { return style()->backgroundColor(); }
 
-
-    void startRow();
-    void addCell( RenderTableCell *cell );
-    void endTable();
-    void  addColInfo(RenderTableCell *cell, bool recalc = true);
-    void  addColInfo(RenderTableCol *colel);
-
-    void addColInfo(int _startCol, int _colSpan,
-                    int _minSize, int _maxSize, khtml::Length _width,
-                    RenderTableCell* _cell, bool recalc = true);
-
-    void recalcColInfos();
+    uint cellPadding() const { return padding; }
+    void setCellPadding( uint p ) { padding = p; }
 
     // overrides
     virtual int overflowHeight() const { return height(); }
     virtual int overflowWidth() const { return width(); }
     virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
-    virtual void paint(QPainter *, int x, int y, int w, int h,
-                       int tx, int ty, int paintPhase);
+    virtual void paint( QPainter *, int x, int y, int w, int h,
+                        int tx, int ty, int paintPhase);
     virtual void layout();
     virtual void calcMinMaxWidth();
     virtual void close();
 
     virtual short lineHeight(bool b) const;
     virtual short baselinePosition(bool b) const;
-    
-    virtual void setCellWidths( );
 
-    int cellPadding() { return m_cellPadding; }
-    void setCellPadding(int cellPadding) { m_cellPadding = cellPadding; }
-    
-    int getBaseline(int row) {return rowInfo[row].baseline;}
+    virtual void setCellWidths( );
 
     virtual void position(int x, int y, int from, int len, int width, bool reverse, bool firstLine, int);
 
@@ -132,160 +115,89 @@ public:
     virtual int borderTopExtra();
     virtual int borderBottomExtra();
 
-    void closeRow();
-    void setNeedsCellsRecalc();
-    void recalcCells();
-
 #ifndef NDEBUG
     virtual void dump(QTextStream *stream, QString ind = "") const;
 #endif
-
-public:
-    /*
-     * For each table element with a different width a ColInfo struct is
-     * maintained. Consider for example the following table:
-     * +---+---+---+
-     * | A | B | C |
-     * +---+---+---+
-     * |   D   | E |
-     * +-------+---+
-     *
-     * This table would result in 4 ColInfo structs being allocated.
-     * 1 for A, 1 for B, 1 for C & E, and 1 for D.
-     *
-     * Note that C and E share the same ColInfo.
-     *
-     * Note that D has a seperate ColInfo entry.
-     *
-     * There is always 1 default ColInfo entry which stretches across the
-     * entire table.
-     */
-    struct ColInfo
-    {
-        ColInfo()
-        {
-	    needsRecalc();
-        }
-
-        void needsRecalc() {
-            span = start = min = max = value = 0;
-            minCell = maxCell = widthCell = 0;
-            type=khtml::Variable;
-            needRecalc = true;
-        }
-            
-        int     span;
-        int     start;
-        int     min;
-        int     max;
-        RenderTableCell* minCell;
-        RenderTableCell* maxCell;
-        khtml::LengthType       type;
-        int     value;
-	RenderTableCell* widthCell;
-        bool    needRecalc;
-    };
-
-    struct RowInfo
-    {
-        int height;
-        int percentage;
-        int baseline;
+    struct ColumnStruct {
+	enum {
+	    WidthUndefined = 0xffff
+	};
+	ColumnStruct() {
+	    span = 1;
+	    width = WidthUndefined;
+	}
+	ushort span;
+	ushort width; // the calculated position of the column
     };
-    
-protected:
-
-    void recalcColInfo( ColInfo *col );
 
-    // This function calculates the actual widths of the columns
-    void calcColWidth();
-
-    // calculates the height of each row
-    void calcRowHeight(int r);
+    QMemArray<int> columnPos;
+    QMemArray<ColumnStruct> columns;
+
+    void splitColumn( int pos, int firstSpan );
+    void appendColumn( int span );
+    int numEffCols() const { return columns.size(); }
+    int spanOfEffCol( int effCol ) const { return columns[effCol].span; }
+    int colToEffCol( int col ) const {
+	int c = 0;
+	int i = 0;
+	while ( c < col && i < (int)columns.size() ) {
+	    c += columns[i].span;
+	    i++;
+	}
+	return i;
+    }
+    int effColToCol( int effCol ) const {
+	int c = 0;
+	for ( int i = 0; i < effCol; i++ )
+	    c += columns[i].span;
+	return c;
+    }
 
-    void layoutRows(int yoff);
+    int bordersAndSpacing() const {
+	return borderLeft() + borderRight() + (numEffCols()+1) * cellSpacing();
+    }
 
-    void setCells( unsigned int r, unsigned int c, RenderTableCell *cell );
-    void addRows( int num );
-    void addColumns( int num );
+    RenderTableCol *colElement( int col );
 
-    RenderTableCell ***cells;
+    void setNeedSectionRecalc() { needSectionRecalc = true; }
 
-    class ColInfoLine : public QPtrVector<ColInfo>
-    {
-    public:
-        ColInfoLine() : QPtrVector<ColInfo>()
-        { setAutoDelete(true); }
-        ColInfoLine(int i) : QPtrVector<ColInfo>(i)
-        { setAutoDelete(true); }
-        ColInfoLine(const QPtrVector<ColInfo> &v) : QPtrVector<ColInfo>(v)
-        { setAutoDelete(true); }
-    };
+    virtual RenderObject* removeChildNode(RenderObject* child);
 
-    QPtrVector<ColInfoLine> colInfos;
+protected:
 
-    void calcColMinMax();
-    void calcSingleColMinMax(int c, ColInfo* col);
-    void calcFinalColMax(int c, ColInfo* col);
-    void spreadSpanMinMax(int col, int span, int min, int max, khtml::LengthType type);
-    int distributeWidth(int distrib, khtml::LengthType type, int typeCols );
-    int distributeMinWidth(int distrib, khtml::LengthType distType,
-            khtml::LengthType toType, int start, int span, bool minlimit );
-    int distributeMaxWidth(int distrib, LengthType distType,
-            LengthType toType, int start, int span);
-    int distributeRest(int distrib, khtml::LengthType type, int divider );
+    void recalcSections();
 
-    int maxColSpan;
+    friend class AutoTableLayout;
+    friend class FixedTableLayout;
 
-    QMemArray<RowInfo> rowInfo;
-   
-    QMemArray<int> columnPos;
-    QMemArray<int> colMaxWidth;
-    QMemArray<int> colMinWidth;
-    QMemArray<khtml::LengthType> colType;
-    QMemArray<int> colValue;
-    QMemArray<int> actColWidth;
-    unsigned int col;
-    unsigned int totalCols;
-    unsigned int row;
-    unsigned int totalRows;
-    unsigned int allocRows;
-
-    unsigned int totalPercent ;
-    unsigned int totalRelative ;
-
-    RenderTableCaption *tCaption;
+    RenderFlow         *tCaption;
     RenderTableSection *head;
     RenderTableSection *foot;
     RenderTableSection *firstBody;
 
-    Frame frame;
-    Rules rules;
+    TableLayout *tableLayout;
 
-    int m_cellPadding;
-    
-    RenderTableCol *_oldColElem;
-    int _currentCol; // keeps track of current col for col/colgroup stuff
-    int spacing;
-    short _lastParentWidth 	: 16;
-    bool incremental 		: 1;
-    bool collapseBorders 	: 1;
-    bool colWidthKnown 		: 1;
-    bool needsCellsRecalc 	: 1;
-    bool hasPercent 		: 1;
+    Frame frame                 : 4;
+    Rules rules                 : 4;
+
+    bool has_col_elems		: 1;
+    uint spacing                : 11;
+    uint padding		: 11;
+    uint needSectionRecalc	: 1;
 };
 
 // -------------------------------------------------------------------------
 
-class RenderTableSection : public RenderContainer
+class RenderTableSection : public RenderBox
 {
 public:
     RenderTableSection(DOM::NodeImpl* node);
     ~RenderTableSection();
+    virtual void detach(RenderArena* arena);
 
-    virtual const char *renderName() const { return "RenderTableSection"; }
+    virtual void setStyle(RenderStyle *style);
 
-    int numRows() { return nrows; }
+    virtual const char *renderName() const { return "RenderTableSection"; }
 
     // overrides
     virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
@@ -294,15 +206,58 @@ public:
     virtual short lineHeight(bool) const { return 0; }
     virtual void position(int, int, int, int, int, bool, bool, int) {}
 
-    virtual void setTable(RenderTable *t) { table = t; }
-
 #ifndef NDEBUG
     virtual void dump(QTextStream *stream, QString ind = "") const;
 #endif
 
+    void addCell( RenderTableCell *cell );
+
+    void setCellWidths();
+    void calcRowHeight();
+    int layoutRows( int height );
+
+    RenderTable *table() const { return static_cast<RenderTable *>(parent()); }
+
+    typedef QMemArray<RenderTableCell *> Row;
+    struct RowStruct {
+	Row *row;
+	int baseLine;
+	Length height;
+    };
+
+    RenderTableCell *&cellAt( int row,  int col ) {
+	return (*(grid[row].row))[col];
+    }
+    RenderTableCell *cellAt( int row,  int col ) const {
+	return (*(grid[row].row))[col];
+    }
+
+    virtual void paint( QPainter *, int x, int y, int w, int h,
+                        int tx, int ty, int paintPhase);
+
+    int numRows() const { return grid.size(); }
+    int getBaseline(int row) {return grid[row].baseLine;}
+
+    void setNeedCellRecalc() {
+        needCellRecalc = true;
+        table()->setNeedSectionRecalc();
+    }
+
+    virtual RenderObject* removeChildNode(RenderObject* child);
+
+    // this gets a cell grid data structure. changing the number of
+    // columns is done by the table
+    QMemArray<RowStruct> grid;
+    QMemArray<int> rowPos;
+
+    ushort cCol : 15;
+    short cRow : 16;
+    bool needCellRecalc : 1;
+
+    void recalcCells();
 protected:
-    RenderTable *table;
-    int nrows;
+    void ensureRows( int numRows );
+    void clearGrid();
 };
 
 // -------------------------------------------------------------------------
@@ -311,42 +266,29 @@ class RenderTableRow : public RenderContainer
 {
 public:
     RenderTableRow(DOM::NodeImpl* node);
-    ~RenderTableRow();
-
-    virtual const char *renderName() const { return "RenderTableRow"; }
 
-    long rowIndex() const;
-    void setRowIndex( long );
+    virtual void detach(RenderArena* arena);
 
-    long sectionRowIndex() const { return rIndex; }
-    void setSectionRowIndex( long i ) { rIndex = i; }
+    virtual void setStyle( RenderStyle* );
+    virtual const char *renderName() const { return "RenderTableRow"; }
 
     virtual bool isTableRow() const { return true; }
 
     // overrides
     virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
+    virtual RenderObject* removeChildNode(RenderObject* child);
 
     virtual short lineHeight( bool ) const { return 0; }
     virtual void position(int, int, int, int, int, bool, bool, int) {}
 
-    virtual void close();
-
-    virtual void repaint(bool immediate=false);
-
     virtual void layout();
 
-    virtual void setTable(RenderTable *t) { table = t; }
+    RenderTable *table() const { return static_cast<RenderTable *>(parent()->parent()); }
+    RenderTableSection *section() const { return static_cast<RenderTableSection *>(parent()); }
 
 #ifndef NDEBUG
     virtual void dump(QTextStream *stream, QString ind = "") const;
 #endif
-
-protected:
-    RenderTable *table;
-
-    // relative to the current section!
-    int rIndex;
-    int ncols;
 };
 
 // -------------------------------------------------------------------------
@@ -355,7 +297,8 @@ class RenderTableCell : public RenderFlow
 {
 public:
     RenderTableCell(DOM::NodeImpl* node);
-    ~RenderTableCell();
+
+    virtual void detach(RenderArena* arena);
 
     virtual const char *renderName() const { return "RenderTableCell"; }
     virtual bool isTableCell() const { return true; }
@@ -364,56 +307,33 @@ public:
     long cellIndex() const { return 0; }
     void setCellIndex( long ) { }
 
-    long colSpan() const { return cSpan; }
-    void setColSpan( long c ) { cSpan = c; }
+    unsigned short colSpan() const { return cSpan; }
+    void setColSpan( unsigned short c ) { cSpan = c; }
 
-    long rowSpan() const { return rSpan; }
-    void setRowSpan( long r ) { rSpan = r; }
-
-    bool noWrap() const { return nWrap; }
-    void setNoWrap(bool nw) { nWrap = nw; }
+    unsigned short rowSpan() const { return rSpan; }
+    void setRowSpan( unsigned short r ) { rSpan = r; }
 
     int col() const { return _col; }
     void setCol(int col) { _col = col; }
     int row() const { return _row; }
     void setRow(int r) { _row = r; }
 
-    khtml::LengthType colType();
-
     // overrides
     virtual void calcMinMaxWidth();
     virtual void calcWidth();
     virtual void setWidth( int width );
     virtual void setStyle( RenderStyle *style );
-    virtual void repaint(bool immediate=false);
-    
-    virtual int paddingTop() const;
-    virtual int paddingBottom() const;
-    virtual int paddingLeft() const;
-    virtual int paddingRight() const;
-    virtual bool hasPadding() const { 
-        if (m_table && m_table->cellPadding() != -1)
-            return true;
-        return style()->hasPadding();
-    }
-    
-    virtual void updateFromElement();
 
-    void setRowHeight(int h) { rowHeight = h; }
-    
-    int getCellPercentageHeight() { return cellPercentageHeight; }
-    void setCellPercentageHeight(int h) { cellPercentageHeight = h; }
-    
-    void setRowImpl(RenderTableRow *r) { rowimpl = r; }
+    virtual void updateFromElement();
 
     void setCellTopExtra(int p) { _topExtra = p; }
     void setCellBottomExtra(int p) { _bottomExtra = p; }
 
-    virtual void setTable(RenderTable *t) { m_table = t; }
-    RenderTable *table() const { return m_table; }
-
-    virtual void paint(QPainter* p, int x, int y,
-                       int w, int h, int tx, int ty, int paintPhase);
+    int getCellPercentageHeight() const;
+    void setCellPercentageHeight(int h);
+    
+    virtual void paint( QPainter* p, int x, int y,
+                        int w, int h, int tx, int ty, int paintPhase);
 
     virtual void close();
 
@@ -428,6 +348,9 @@ public:
     virtual int borderTopExtra() { return _topExtra; }
     virtual int borderBottomExtra() { return _bottomExtra; }
 
+    RenderTable *table() const { return static_cast<RenderTable *>(parent()->parent()->parent()); }
+    RenderTableSection *section() const { return static_cast<RenderTableSection *>(parent()->parent()); }
+
 #ifndef NDEBUG
     virtual void dump(QTextStream *stream, QString ind = "") const;
 #endif
@@ -439,51 +362,42 @@ public:
     }
 
 protected:
-    RenderTable *m_table;
-
     virtual void paintBoxDecorations(QPainter *p,int _x, int _y,
                                      int _w, int _h, int _tx, int _ty);
-
+    
     short _row;
     short _col;
-    short rSpan;
-    short cSpan;
-    int _id;
-    int rowHeight;
-    int cellPercentageHeight;
-    int _topExtra;
-    int _bottomExtra;
+    ushort rSpan;
+    ushort cSpan;
+    int _topExtra : 31;
     bool nWrap : 1;
+    int _bottomExtra : 31;
     bool m_widthChanged : 1;
-
-    RenderTableRow *rowimpl;
+    
+    int m_percentageHeight;
 };
 
+
 // -------------------------------------------------------------------------
 
 class RenderTableCol : public RenderContainer
 {
 public:
     RenderTableCol(DOM::NodeImpl* node);
-    ~RenderTableCol();
 
     virtual const char *renderName() const { return "RenderTableCol"; }
 
-    void setStartCol( int c ) {_startCol = _currentCol = c; }
-    int col() { return _startCol; }
-    int lastCol() { return _currentCol; }
-
     long span() const { return _span; }
     void setSpan( long s ) { _span = s; }
 
     virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
 
+    virtual bool isTableCol() const { return true; }
+
     virtual short lineHeight( bool ) const { return 0; }
     virtual void position(int, int, int, int, int, bool, bool, int) {}
     virtual void layout() {}
 
-    virtual void setTable(RenderTable *t) { table = t; }
-
     virtual void updateFromElement();
 
 #ifndef NDEBUG
@@ -491,30 +405,7 @@ public:
 #endif
 
 protected:
-    RenderTable *table;
-    int _span;
-    int _currentCol;
-    int _startCol;
-
-    // could be ID_COL or ID_COLGROUP ... The DOM is not quite clear on
-    // this, but since both elements work quite similar, we use one
-    // DOMElement for them...
-    ushort _id;
-};
-
-// -------------------------------------------------------------------------
-
-class RenderTableCaption : public RenderFlow
-{
-public:
-    RenderTableCaption(DOM::NodeImpl*);
-    ~RenderTableCaption();
-
-    virtual const char *renderName() const { return "RenderTableCaption"; }
-
-    virtual void setTable(RenderTable *t) { table = t; }
-protected:
-    RenderTable *table;
+    short _span;
 };
 
 };
diff --git a/WebCore/khtml/rendering/table_layout.cpp b/WebCore/khtml/rendering/table_layout.cpp
new file mode 100644
index 0000000..656d2a1
--- /dev/null
+++ b/WebCore/khtml/rendering/table_layout.cpp
@@ -0,0 +1,1016 @@
+/*
+ * This file is part of the HTML rendering engine for KDE.
+ *
+ * Copyright (C) 2002 Lars Knoll (knoll at kde.org)
+ *           (C) 2002 Dirk Mueller (mueller at kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+#include "table_layout.h"
+#include "render_table.h"
+
+#include <kglobal.h>
+
+using namespace khtml;
+
+// #define DEBUG_LAYOUT
+
+/*
+  The text below is from the CSS 2.1 specs.
+
+  Fixed table layout
+  ------------------
+
+  With this (fast) algorithm, the horizontal layout of the table does
+  not depend on the contents of the cells; it only depends on the
+  table's width, the width of the columns, and borders or cell
+  spacing.
+
+  The table's width may be specified explicitly with the 'width'
+  property. A value of 'auto' (for both 'display: table' and 'display:
+  inline-table') means use the automatic table layout algorithm.
+
+  In the fixed table layout algorithm, the width of each column is
+  determined as follows:
+
+    1. A column element with a value other than 'auto' for the 'width'
+    property sets the width for that column.
+
+    2.Otherwise, a cell in the first row with a value other than
+    'auto' for the 'width' property sets the width for that column. If
+    the cell spans more than one column, the width is divided over the
+    columns.
+
+    3. Any remaining columns equally divide the remaining horizontal
+    table space (minus borders or cell spacing).
+
+  The width of the table is then the greater of the value of the
+  'width' property for the table element and the sum of the column
+  widths (plus cell spacing or borders). If the table is wider than
+  the columns, the extra space should be distributed over the columns.
+
+
+  In this manner, the user agent can begin to lay out the table once
+  the entire first row has been received. Cells in subsequent rows do
+  not affect column widths. Any cell that has content that overflows
+  uses the 'overflow' property to determine whether to clip the
+  overflow content.
+
+_____________________________________________________
+
+  This is not quite true when comparing to IE. IE always honours
+  table-layout:fixed and treats a variable table width as 100%. Makes
+  a lot of sense, and is implemented here the same way.
+
+*/
+
+FixedTableLayout::FixedTableLayout( RenderTable *table )
+    : TableLayout ( table )
+{
+}
+
+FixedTableLayout::~FixedTableLayout()
+{
+}
+
+int FixedTableLayout::calcWidthArray( int tableWidth )
+{
+    int usedWidth = 0;
+
+    // iterate over all <col> elements
+    RenderObject *child = table->firstChild();
+    int cCol = 0;
+    int nEffCols = table->numEffCols();
+    width.resize( nEffCols );
+    width.fill( Length( Variable ) );
+
+#ifdef DEBUG_LAYOUT
+    qDebug("FixedTableLayout::calcWidthArray( %d )", tableWidth );
+    qDebug("    col elements:");
+#endif
+
+    Length grpWidth;
+    while ( child ) {
+	if ( child->isTableCol() ) {
+	    RenderTableCol *col = static_cast<RenderTableCol *>(child);
+	    int span = col->span();
+	    if ( col->firstChild() ) {
+		grpWidth = col->style()->width();
+	    } else {
+		Length w = col->style()->width();
+		if ( w.isVariable() )
+		    w = grpWidth;
+		int effWidth = 0;
+		if ( w.type == Fixed && w.value > 0 ) {
+                    effWidth = w.value;
+		    effWidth = QMIN( effWidth, 32760 );
+		}
+#ifdef DEBUG_LAYOUT
+		qDebug("    col element: effCol=%d, span=%d: %d w=%d type=%d",
+		       cCol, span, effWidth,  w.value, w.type);
+#endif
+		int usedSpan = 0;
+		int i = 0;
+		while ( usedSpan < span ) {
+		    if( cCol + i >= nEffCols ) {
+			table->appendColumn( span - usedSpan );
+			nEffCols++;
+			width.resize( nEffCols );
+			width[nEffCols-1] = Length();
+		    }
+		    int eSpan = table->spanOfEffCol( cCol+i );
+		    if ( (w.type == Fixed || w.type == Percent) && w.value > 0 ) {
+			width[cCol+i] = Length( w.value * eSpan, w.type );
+			usedWidth += effWidth * eSpan;
+#ifdef DEBUG_LAYOUT
+			qDebug("    setting effCol %d (span=%d) to width %d(type=%d)",
+			       cCol+i, eSpan, width[cCol+i].value, width[cCol+i].type );
+#endif
+		    }
+		    usedSpan += eSpan;
+		    i++;
+		}
+		cCol += i;
+	    }
+	} else {
+	    break;
+	}
+
+	RenderObject *next = child->firstChild();
+	if ( !next )
+	    next = child->nextSibling();
+	if ( !next && child->parent()->isTableCol() ) {
+	    next = child->parent()->nextSibling();
+	    grpWidth = Length();
+	}
+	child = next;
+    }
+
+#ifdef DEBUG_LAYOUT
+    qDebug("    first row:");
+#endif
+    // iterate over the first row in case some are unspecified.
+    RenderTableSection *section = table->head;
+    if ( !section )
+	section = table->firstBody;
+    if ( !section )
+	section = table->foot;
+    if ( section ) {
+	cCol = 0;
+	// get the first cell in the first row
+	child = section->firstChild()->firstChild();
+	while ( child ) {
+	    if ( child->isTableCell() ) {
+		RenderTableCell *cell = static_cast<RenderTableCell *>(child);
+		Length w = cell->style()->width();
+		int span = cell->colSpan();
+		int effWidth = 0;
+		if ( (w.type == Fixed || w.type == Percent) && w.value > 0 ) {
+                    effWidth = w.value;
+		    effWidth = QMIN( effWidth, 32760 );
+		}
+#ifdef DEBUG_LAYOUT
+		qDebug("    table cell: effCol=%d, span=%d: %d",  cCol, span, effWidth);
+#endif
+		int usedSpan = 0;
+		int i = 0;
+		while ( usedSpan < span ) {
+		    Q_ASSERT( cCol + i < nEffCols );
+		    int eSpan = table->spanOfEffCol( cCol+i );
+		    // only set if no col element has already set it.
+		    if ( width[cCol+i].type == Variable && w.type != Variable ) {
+			width[cCol+i] = Length( w.value*eSpan, w.type );
+			usedWidth += effWidth*eSpan;
+#ifdef DEBUG_LAYOUT
+			qDebug("    setting effCol %d (span=%d) to width %d(type=%d)",
+			       cCol+i, eSpan, width[cCol+i].value, width[cCol+i].type );
+#endif
+		    }
+#ifdef DEBUG_LAYOUT
+		    else {
+			qDebug("    width of col %d already defined (span=%d)", cCol, table->spanOfEffCol( cCol ) );
+		    }
+#endif
+		    usedSpan += eSpan;
+		    i++;
+		}
+		cCol += i;
+	    } else {
+		Q_ASSERT( false );
+	    }
+	    child = child->nextSibling();
+	}
+    }
+
+    return usedWidth;
+
+}
+
+void FixedTableLayout::calcMinMaxWidth()
+{
+    // we might want to wait until we have all of the first row before
+    // layouting for the first time.
+
+    // only need to calculate the minimum width as the sum of the
+    // cols/cells with a fixed width.
+    //
+    // The maximum width is kMax( minWidth, tableWidth ) if table
+    // 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 - bs : 0;
+
+    table->m_minWidth = calcWidthArray( tableWidth );
+    table->m_minWidth += bs;
+
+    table->m_minWidth = kMax( table->m_minWidth, tableWidth );
+    table->m_maxWidth = table->m_minWidth;
+    if ( !tableWidth ) {
+	bool haveNonFixed = false;
+	for ( unsigned int i = 0; i < width.size(); i++ ) {
+	    if ( !(width[i].type == Fixed) ) {
+		haveNonFixed = true;
+		break;
+	    }
+	}
+	if ( haveNonFixed )
+	    table->m_maxWidth = 0x7fff;
+    }
+#ifdef DEBUG_LAYOUT
+    qDebug("FixedTableLayout::calcMinMaxWidth: minWidth=%d, maxWidth=%d", table->m_minWidth, table->m_maxWidth );
+#endif
+}
+
+void FixedTableLayout::layout()
+{
+    int tableWidth = table->width() - table->bordersAndSpacing();
+    int available = tableWidth;
+    int nEffCols = table->numEffCols();
+#ifdef DEBUG_LAYOUT
+    qDebug("FixedTableLayout::layout: tableWidth=%d, numEffCols=%d",  tableWidth, nEffCols);
+#endif
+
+
+    QMemArray<short> calcWidth;
+    calcWidth.resize( nEffCols );
+    calcWidth.fill( -1 );
+
+    // first assign  fixed width
+    for ( int i = 0; i < nEffCols; i++ ) {
+	if ( width[i].type == Fixed ) {
+	    calcWidth[i] = width[i].value;
+	    available -= width[i].value;
+	}
+    }
+
+    // assign  percent width
+    if ( available > 0 ) {
+	int totalPercent = 0;
+	for ( int i = 0; i < nEffCols; i++ )
+	    if ( width[i].type == Percent )
+		totalPercent += width[i].value;
+
+	// calculate how much to distribute to percent cells.
+	int base = tableWidth * totalPercent / 100;
+	if ( base > available )
+	    base = available;
+	else
+	    totalPercent = 100;
+
+#ifdef DEBUG_LAYOUT
+    qDebug("FixedTableLayout::layout: assigning percent width, base=%d, totalPercent=%d", base, totalPercent);
+#endif
+        for ( int i = 0; available > 0 && i < nEffCols; i++ ) {
+            if ( width[i].type == Percent ) {
+                int w = base * width[i].value / totalPercent;
+                available -= w;
+                calcWidth[i] = w;
+            }
+        }
+    }
+
+    // assign  variable width
+    if ( available > 0 ) {
+	int totalVariable = 0;
+	for ( int i = 0; i < nEffCols; i++ )
+	    if ( width[i].type == Variable )
+		totalVariable++;
+
+        for ( int i = 0; available > 0 && i < nEffCols; i++ ) {
+            if ( width[i].type == Variable ) {
+                int w = available / totalVariable;
+                available -= w;
+                calcWidth[i] = w;
+		totalVariable--;
+            }
+        }
+    }
+
+    for ( int i = 0; i < nEffCols; i++ )
+	if ( calcWidth[i] <= 0 )
+	    calcWidth[i] = 0; // IE gives min 1 px...
+
+    int pos = 0;
+    int spacing = table->cellSpacing();
+    for ( int i = 0; i < nEffCols; i++ ) {
+#ifdef DEBUG_LAYOUT
+	qDebug("col %d: %d (width %d)", i, pos, calcWidth[i] );
+#endif
+	table->columnPos[i] = pos;
+	pos += calcWidth[i] + spacing;
+    }
+    table->columnPos[table->columnPos.size()-1] = pos;
+}
+
+// -------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+
+
+AutoTableLayout::AutoTableLayout( RenderTable* table )
+    : TableLayout( table )
+{
+    percentagesDirty = true;
+    effWidthDirty = true;
+    total_percent = 0;
+    hasPercent = false;
+}
+
+AutoTableLayout::~AutoTableLayout()
+{
+}
+
+/* recalculates the full structure needed to do layouting and minmax calculations.
+   This is usually calculated on the fly, but needs to be done fully when table cells change
+   dynamically
+*/
+void AutoTableLayout::recalcColumn( int effCol )
+{
+    Layout &l = layoutStruct[effCol];
+
+    RenderObject *child = table->firstChild();
+    // first we iterate over all rows.
+
+    RenderTableCell *fixedContributor = 0;
+    RenderTableCell *maxContributor = 0;
+
+    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 )
+		    continue;
+		if ( cell && cell->colSpan() == 1 ) {
+		    if ( !cell->minMaxKnown() )
+			cell->calcMinMaxWidth();
+		    if ( cell->minWidth() > l.minWidth )
+			l.minWidth = cell->minWidth();
+		    if ( cell->maxWidth() > l.maxWidth ) {
+			l.maxWidth = cell->maxWidth();
+			maxContributor = cell;
+		    }
+
+		    Length w = cell->style()->width();
+		    if ( w.value > 32760 )
+			w.value = 32760;
+		    if ( w.value < 0 )
+			w.value = 0;
+		    switch( w.type ) {
+		    case Fixed:
+			// ignore width=0
+			if ( w.value > 0 && (int)l.width.type != Percent ) {
+                            // ### we should use box'es paddings here I guess.
+                            int wval = w.value + table->cellPadding() * 2;
+			    if ( l.width.type == Fixed ) {
+                                // Nav/IE weirdness
+				if ((wval > l.width.value) ||
+				    ((l.width.value == wval) && (maxContributor == cell))) {
+				    l.width.value = wval;
+				    fixedContributor = cell;
+				}
+			    } else {
+                                l.width.type = Fixed;
+				l.width.value = wval;
+				fixedContributor = cell;
+			    }
+			}
+			break;
+		    case Percent:
+                        hasPercent = true;
+                        if ( w.value > 0 && (l.width.type != Percent || w.value > l.width.value ) )
+                            l.width = w;
+			break;
+		    case Relative:
+			if ( w.type == Variable || (w.type == Relative && w.value > l.width.value ) )
+				l.width = w;
+		    default:
+			break;
+		    }
+		} else {
+		    if ( !effCol || section->cellAt( i, effCol-1 ) != cell )
+			insertSpanCell( cell );
+		    last = cell;
+		}
+	    }
+	}
+	child = child->nextSibling();
+    }
+
+    // Nav/IE weirdness
+    if ( l.width.type == Fixed ) {
+	if ( table->style()->htmlHacks()
+	     && (l.maxWidth > l.width.value) && (fixedContributor != maxContributor)) {
+	    l.width = Length();
+	    fixedContributor = 0;
+	}
+    }
+
+    l.maxWidth = kMax(l.maxWidth, l.minWidth);
+#ifdef DEBUG_LAYOUT
+    qDebug("col %d, final min=%d, max=%d, width=%d(%d)", effCol, l.minWidth, l.maxWidth, l.width.value,  l.width.type );
+#endif
+
+    // ### we need to add col elements aswell
+}
+
+
+void AutoTableLayout::fullRecalc()
+{
+    percentagesDirty = true;
+    hasPercent = false;
+    effWidthDirty = true;
+
+    int nEffCols = table->numEffCols();
+    layoutStruct.resize( nEffCols );
+    layoutStruct.fill( Layout() );
+    spanCells.fill( 0 );
+
+    RenderObject *child = table->firstChild();
+    Length grpWidth;
+    int cCol = 0;
+    while ( child ) {
+	if ( child->isTableCol() ) {
+	    RenderTableCol *col = static_cast<RenderTableCol *>(child);
+	    int span = col->span();
+	    if ( col->firstChild() ) {
+		grpWidth = col->style()->width();
+	    } else {
+		Length w = col->style()->width();
+		if ( w.isVariable() )
+		    w = grpWidth;
+		if ( (w.type == Fixed && w.value == 0) ||
+		     (w.type == Percent && w.value == 0) )
+		    w = Length();
+		int cEffCol = table->colToEffCol( cCol );
+#ifdef DEBUG_LAYOUT
+		qDebug("    col element %d (eff=%d): Length=%d(%d), span=%d, effColSpan=%d",  cCol, cEffCol, w.value, w.type, span, table->spanOfEffCol(cEffCol ) );
+#endif
+		if ( (int)w.type != Variable && span == 1 && cEffCol < nEffCols ) {
+		    if ( table->spanOfEffCol( cEffCol ) == 1 ) {
+			layoutStruct[cEffCol].width = w;
+                        if (w.isFixed() && layoutStruct[cEffCol].maxWidth < w.value)
+                            layoutStruct[cEffCol].maxWidth = w.value;
+                    }
+		}
+		cCol += span;
+	    }
+	} else {
+	    break;
+	}
+
+	RenderObject *next = child->firstChild();
+	if ( !next )
+	    next = child->nextSibling();
+	if ( !next && child->parent()->isTableCol() ) {
+	    next = child->parent()->nextSibling();
+	    grpWidth = Length();
+	}
+	child = next;
+    }
+
+
+    for ( int i = 0; i < nEffCols; i++ )
+	recalcColumn( i );
+}
+
+
+void AutoTableLayout::calcMinMaxWidth()
+{
+#ifdef DEBUG_LAYOUT
+    qDebug("AutoTableLayout::calcMinMaxWidth");
+#endif
+    fullRecalc();
+
+    int spanMaxWidth = calcEffectiveWidth();
+    int minWidth = 0;
+    int maxWidth = 0;
+    int maxPercent = 0;
+    int maxNonPercent = 0;
+
+    for ( unsigned int i = 0; i < layoutStruct.size(); i++ ) {
+	minWidth += layoutStruct[i].effMinWidth;
+	maxWidth += layoutStruct[i].effMaxWidth;
+	if ( layoutStruct[i].effWidth.type == Percent ) {
+	    int pw = ( layoutStruct[i].effMaxWidth * 100) / layoutStruct[i].effWidth.value;
+	    maxPercent = kMax( pw,  maxPercent );
+	} else {
+	    maxNonPercent += layoutStruct[i].effMaxWidth;
+	}
+    }
+
+    int totalpct = totalPercent();
+    if (totalpct >= 100)
+        totalpct = 99;
+    
+    maxNonPercent = (maxNonPercent * 100 + 50) / (100-totalpct);
+	maxWidth = kMax( maxNonPercent,  maxWidth );
+   
+    maxWidth = kMax( maxWidth, maxPercent );
+    maxWidth = kMax( maxWidth, spanMaxWidth );
+
+    int bs = table->bordersAndSpacing();
+    minWidth += bs;
+    maxWidth += bs;
+
+    Length tw = table->style()->width();
+    if ( tw.isFixed() && tw.value > 0 ) {
+	minWidth = kMax( minWidth, int( tw.value ) );
+	maxWidth = minWidth;
+    }
+
+    table->m_maxWidth = maxWidth;
+    table->m_minWidth = minWidth;
+#ifdef DEBUG_LAYOUT
+    qDebug("    minWidth=%d, maxWidth=%d", table->m_minWidth, table->m_maxWidth );
+#endif
+}
+
+/*
+  This method takes care of colspans.
+  effWidth is the same as width for cells without colspans. If we have colspans, they get modified.
+ */
+int AutoTableLayout::calcEffectiveWidth()
+{
+    int tMaxWidth = 0;
+
+    unsigned int nEffCols = layoutStruct.size();
+    int spacing = table->cellSpacing();
+#ifdef DEBUG_LAYOUT
+    qDebug("AutoTableLayout::calcEffectiveWidth for %d cols", nEffCols );
+#endif
+    for ( unsigned int i = 0; i < nEffCols; i++ ) {
+	layoutStruct[i].effWidth = layoutStruct[i].width;
+	layoutStruct[i].effMinWidth = layoutStruct[i].minWidth;
+	layoutStruct[i].effMaxWidth = layoutStruct[i].maxWidth;
+    }
+
+    for ( unsigned int i = 0; i < spanCells.size(); i++ ) {
+	RenderTableCell *cell = spanCells[i];
+	if ( !cell || cell == (RenderTableCell *)-1 )
+	    break;
+	int span = cell->colSpan();
+
+	Length w = cell->style()->width();
+	if ( !(w.type == Relative) && w.value == 0 )
+	    w = Length(); // make it Variable
+
+	int col = table->colToEffCol( cell->col() );
+	unsigned int lastCol = col;
+	int cMinWidth = cell->minWidth() + spacing;
+	int cMaxWidth = cell->maxWidth() + spacing;
+	int totalPercent = 0;
+	int minWidth = 0;
+	int maxWidth = 0;
+	bool allColsArePercent = true;
+	bool allColsAreFixed = true;
+	bool haveVariable = false;
+	int fixedWidth = 0;
+#ifdef DEBUG_LAYOUT
+	int cSpan = span;
+#endif
+	while ( lastCol < nEffCols && span > 0 ) {
+	    switch( layoutStruct[lastCol].width.type ) {
+	    case Percent:
+		totalPercent += layoutStruct[lastCol].width.value;
+		allColsAreFixed = false;
+		break;
+	    case Fixed:
+                if (layoutStruct[lastCol].width.value > 0) {
+                    fixedWidth += layoutStruct[lastCol].width.value;
+                    allColsArePercent = false;
+                    // IE resets effWidth to Variable here, but this breaks the konqueror about page and seems to be some bad
+                    // legacy behaviour anyway. mozilla doesn't do this so I decided we don't neither.
+                    break;
+                }
+                // fall through
+	    case Variable:
+		haveVariable = true;
+		// fall through
+	    default:
+		layoutStruct[lastCol].effWidth = Length();
+		allColsArePercent = false;
+		allColsAreFixed = false;
+	    }
+	    span -= table->spanOfEffCol( lastCol );
+	    minWidth += layoutStruct[lastCol].effMinWidth;
+	    maxWidth += layoutStruct[lastCol].effMaxWidth;
+	    lastCol++;
+	    cMinWidth -= spacing;
+	    cMaxWidth -= spacing;
+	}
+#ifdef DEBUG_LAYOUT
+	qDebug("    colspan cell %p at effCol %d, span %d, type %d, value %d cmin=%d min=%d fixedwidth=%d", cell, col, cSpan, w.type, w.value, cMinWidth, minWidth, fixedWidth );
+#endif
+
+	// adjust table max width if needed
+	if ( w.type == Percent ) {
+	    if ( totalPercent > w.value || allColsArePercent ) {
+		// can't satify this condition, treat as variable
+		w = Length();
+	    } else {
+		int spanMax = QMAX( maxWidth, cMaxWidth );
+#ifdef DEBUG_LAYOUT
+		qDebug("    adjusting tMaxWidth (%d): spanMax=%d, value=%d, totalPercent=%d", tMaxWidth, spanMax, w.value, totalPercent );
+#endif
+		tMaxWidth = QMAX( tMaxWidth, spanMax * 100 / w.value );
+
+		// all non percent columns in the span get percent vlaues to sum up correctly.
+		int percentMissing = w.value - totalPercent;
+		int totalWidth = 0;
+		for ( unsigned int pos = col; pos < lastCol; pos++ ) {
+		    if ( !(layoutStruct[pos].width.type == Percent ) )
+			totalWidth += layoutStruct[pos].effMaxWidth;
+		}
+
+		for ( unsigned int pos = col; pos < lastCol && totalWidth > 0; pos++ ) {
+		    if ( !(layoutStruct[pos].width.type == Percent ) ) {
+			int percent = percentMissing * layoutStruct[pos].effMaxWidth / totalWidth;
+#ifdef DEBUG_LAYOUT
+			qDebug("   col %d: setting percent value %d effMaxWidth=%d totalWidth=%d", pos, percent, layoutStruct[pos].effMaxWidth, totalWidth );
+#endif
+			totalWidth -= layoutStruct[pos].effMaxWidth;
+			percentMissing -= percent;
+			if ( percent > 0 )
+			    layoutStruct[pos].effWidth = Length( percent, Percent );
+			else
+			    layoutStruct[pos].effWidth = Length();
+		    }
+		}
+
+	    }
+	}
+
+	// make sure minWidth and maxWidth of the spanning cell are honoured
+	if ( cMinWidth > minWidth ) {
+	    if ( allColsAreFixed ) {
+#ifdef DEBUG_LAYOUT
+		qDebug("extending minWidth of cols %d-%d to %dpx currentMin=%d accroding to fixed sum %d", col, lastCol-1, cMinWidth, minWidth, fixedWidth );
+#endif
+		for ( unsigned int pos = col; fixedWidth > 0 && pos < lastCol; pos++ ) {
+		    int w = QMAX( layoutStruct[pos].effMinWidth, cMinWidth * layoutStruct[pos].width.value / fixedWidth );
+#ifdef DEBUG_LAYOUT
+		    qDebug("   col %d: min=%d, effMin=%d, new=%d", pos, layoutStruct[pos].effMinWidth, layoutStruct[pos].effMinWidth, w );
+#endif
+		    fixedWidth -= layoutStruct[pos].width.value;
+		    cMinWidth -= w;
+		    layoutStruct[pos].effMinWidth = w;
+		}
+
+	    } else {
+#ifdef DEBUG_LAYOUT
+		qDebug("extending minWidth of cols %d-%d to %dpx currentMin=%d", col, lastCol-1, cMinWidth, minWidth );
+#endif
+		int maxw = maxWidth;
+		for ( unsigned int pos = col; minWidth > 0 && pos < lastCol; pos++ ) {
+
+		    int w;
+		    if ( layoutStruct[pos].width.type == Fixed && haveVariable && fixedWidth <= cMinWidth ) {
+			w = QMAX( layoutStruct[pos].effMinWidth, layoutStruct[pos].width.value );
+			fixedWidth -= layoutStruct[pos].width.value;
+		    } else {
+			w = QMAX( layoutStruct[pos].effMinWidth, cMinWidth * layoutStruct[pos].effMaxWidth / maxw );
+		    }
+#ifdef DEBUG_LAYOUT
+		    qDebug("   col %d: min=%d, effMin=%d, new=%d", pos, layoutStruct[pos].effMinWidth, layoutStruct[pos].effMinWidth, w );
+#endif
+		    maxw -= layoutStruct[pos].effMaxWidth;
+		    cMinWidth -= w;
+		    layoutStruct[pos].effMinWidth = w;
+		}
+	    }
+	}
+	if ( !(w.type == Percent ) ) {
+	    if ( cMaxWidth > maxWidth ) {
+#ifdef DEBUG_LAYOUT
+		qDebug("extending maxWidth of cols %d-%d to %dpx", col, lastCol-1, cMaxWidth );
+#endif
+		for ( unsigned int pos = col; maxWidth > 0 && pos < lastCol; pos++ ) {
+		    int w = QMAX( layoutStruct[pos].effMaxWidth, cMaxWidth * layoutStruct[pos].effMaxWidth / maxWidth );
+#ifdef DEBUG_LAYOUT
+		    qDebug("   col %d: max=%d, effMax=%d, new=%d", pos, layoutStruct[pos].effMaxWidth, layoutStruct[pos].effMaxWidth, w );
+#endif
+		    maxWidth -= layoutStruct[pos].effMaxWidth;
+		    cMaxWidth -= w;
+		    layoutStruct[pos].effMaxWidth = w;
+		}
+	    }
+	} else {
+	    for ( unsigned int pos = col; pos < lastCol; pos++ )
+		layoutStruct[pos].maxWidth = QMAX(layoutStruct[pos].maxWidth, layoutStruct[pos].minWidth );
+	}
+    }
+    effWidthDirty = false;
+
+//     qDebug("calcEffectiveWidth: tMaxWidth=%d",  tMaxWidth );
+    return tMaxWidth;
+}
+
+/* gets all cells that originate in a column and have a cellspan > 1
+   Sorts them by increasing cellspan
+*/
+void AutoTableLayout::insertSpanCell( RenderTableCell *cell )
+{
+    if ( !cell || cell == (RenderTableCell *)-1 || cell->colSpan() == 1 )
+	return;
+
+//     qDebug("inserting span cell %p with span %d", cell, cell->colSpan() );
+    int size = spanCells.size();
+    if ( !size || spanCells[size-1] != 0 ) {
+	spanCells.resize( size + 10 );
+	for ( int i = 0; i < 10; i++ )
+	    spanCells[size+i] = 0;
+	size += 10;
+    }
+
+    // add them in sort. This is a slow algorithm, and a binary search or a fast sorting after collection would be better
+    unsigned int pos = 0;
+    int span = cell->colSpan();
+    while ( pos < spanCells.size() && spanCells[pos] && span > spanCells[pos]->colSpan() )
+	pos++;
+    memmove( spanCells.data()+pos+1, spanCells.data()+pos, (size-pos-1)*sizeof( RenderTableCell * ) );
+    spanCells[pos] = cell;
+}
+
+
+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();
+
+    if ( nEffCols != (int)layoutStruct.size() ) {
+	qWarning("WARNING: nEffCols is not equal to layoutstruct!" );
+	fullRecalc();
+	nEffCols = table->numEffCols();
+    }
+#ifdef DEBUG_LAYOUT
+    qDebug("AutoTableLayout::layout()");
+#endif
+
+    if ( effWidthDirty )
+	calcEffectiveWidth();
+
+#ifdef DEBUG_LAYOUT
+    qDebug("    tableWidth=%d,  nEffCols=%d", tableWidth,  nEffCols );
+    for ( int i = 0; i < nEffCols; i++ ) {
+	qDebug("    effcol %d is of type %d value %d, minWidth=%d, maxWidth=%d",
+	       i, layoutStruct[i].width.type, layoutStruct[i].width.value,
+	       layoutStruct[i].minWidth, layoutStruct[i].maxWidth );
+	qDebug("        effective: type %d value %d, minWidth=%d, maxWidth=%d",
+	       layoutStruct[i].effWidth.type, layoutStruct[i].effWidth.value,
+	       layoutStruct[i].effMinWidth, layoutStruct[i].effMaxWidth );
+    }
+#endif
+
+    bool havePercent = false;
+    bool haveRelative = false;
+    int totalRelative = 0;
+    int numVariable = 0;
+    int numFixed = 0;
+    int totalVariable = 0;
+    int totalFixed = 0;
+    int totalPercent = 0;
+    int allocVariable = 0;
+
+    // fill up every cell with it's minWidth
+    for ( int i = 0; i < nEffCols; i++ ) {
+	int w = layoutStruct[i].effMinWidth;
+	layoutStruct[i].calcWidth = w;
+	available -= w;
+	Length& width = layoutStruct[i].effWidth;
+        switch( width.type) {
+        case Percent:
+	    havePercent = true;
+	    totalPercent += width.value;
+            break;
+        case Relative:
+	    haveRelative = true;
+	    totalRelative += width.value;
+            break;
+        case Fixed:
+            numFixed++;
+            totalFixed += layoutStruct[i].effMaxWidth;
+            // fall through
+            break;
+        case Variable:
+        case Static:
+            numVariable++;
+            totalVariable += layoutStruct[i].effMaxWidth;
+            allocVariable += w;
+        }
+    }
+
+    // then allocate width to fixed cols
+    if ( available > 0 ) {
+	for ( int i = 0; i < nEffCols; ++i ) {
+	    Length &width = layoutStruct[i].effWidth;
+	    if ( width.type == Fixed && width.value > layoutStruct[i].calcWidth ) {
+		available += layoutStruct[i].calcWidth - width.value;
+		layoutStruct[i].calcWidth = width.value;
+            }
+	}
+    }
+#ifdef DEBUG_LAYOUT
+    qDebug("fixed satisfied: available is %d", available);
+#endif
+
+    // then allocate width to percent cols
+    if ( available > 0 && havePercent ) {
+	for ( int i = 0; i < nEffCols; i++ ) {
+	    Length &width = layoutStruct[i].effWidth;
+	    if ( width.type == Percent ) {
+                int w = kMax ( int( layoutStruct[i].effMinWidth ), width.minWidth( tableWidth ) );
+		available += layoutStruct[i].calcWidth - w;
+		layoutStruct[i].calcWidth = w;
+	    }
+	}
+	if ( totalPercent > 100 ) {
+	    // remove overallocated space from the last columns
+	    int excess = tableWidth*(totalPercent-100)/100;
+	    for ( int i = nEffCols-1; i >= 0; i-- ) {
+		if ( layoutStruct[i].effWidth.type == Percent ) {
+		    int w = layoutStruct[i].calcWidth;
+		    int reduction = kMin( w,  excess );
+		    // the lines below might look inconsistent, but that's the way it's handled in mozilla
+		    excess -= reduction;
+		    int newWidth = kMax( int (layoutStruct[i].effMinWidth), w - reduction );
+		    available += w - newWidth;
+		    layoutStruct[i].calcWidth = newWidth;
+		    //qDebug("col %d: reducing to %d px (reduction=%d)", i, newWidth, reduction );
+		}
+	    }
+	}
+    }
+#ifdef DEBUG_LAYOUT
+    qDebug("percent satisfied: available is %d", available);
+#endif
+
+    // now satisfy relative
+    if ( available > 0 ) {
+	for ( int i = 0; i < nEffCols; i++ ) {
+	    Length &width = layoutStruct[i].effWidth;
+	    if ( width.type == Relative && width.value != 0 ) {
+		// width=0* gets effMinWidth.
+		int w = width.value*tableWidth/totalRelative;
+		available += layoutStruct[i].calcWidth - w;
+		layoutStruct[i].calcWidth = w;
+	    }
+	}
+    }
+
+    // now satisfy variable
+    if ( available > 0 && numVariable ) {
+	available += allocVariable; // this gets redistributed
+ 	//qDebug("redistributing %dpx to %d variable columns. totalVariable=%d",  available,  numVariable,  totalVariable );
+	for ( int i = 0; i < nEffCols; i++ ) {
+	    Length &width = layoutStruct[i].effWidth;
+	    if ( width.type == Variable && totalVariable != 0 ) {
+		int w = kMax( int ( layoutStruct[i].calcWidth ),
+                              available * layoutStruct[i].effMaxWidth / totalVariable );
+		available -= w;
+		totalVariable -= layoutStruct[i].effMaxWidth;
+		layoutStruct[i].calcWidth = w;
+	    }
+	}
+    }
+#ifdef DEBUG_LAYOUT
+    qDebug("variable satisfied: available is %d",  available );
+#endif
+
+    // spread over fixed colums
+    if ( available > 0 && numFixed) {
+        // still have some width to spread, distribute to fixed columns
+        for ( int i = 0; i < nEffCols; i++ ) {
+            Length &width = layoutStruct[i].effWidth;
+            if ( width.isFixed() ) {
+                int w = available * layoutStruct[i].effMaxWidth / totalFixed;
+                available -= w;
+                totalFixed -= layoutStruct[i].effMaxWidth;
+                layoutStruct[i].calcWidth += w;
+            }
+        }
+    }
+
+#ifdef DEBUG_LAYOUT
+    qDebug("after fixed distribution: available=%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 the rest
+    if ( available > 0 ) {
+        int total = nEffCols;
+        // still have some width to spread
+        int i = nEffCols;
+        while (  i-- ) {
+            int w = available / total;
+            available -= w;
+            total--;
+            layoutStruct[i].calcWidth += w;
+        }
+    }
+
+#ifdef DEBUG_LAYOUT
+    qDebug("after equal distribution: available=%d",  available );
+#endif
+    // if we have overallocated, reduce every cell according to the difference between desired width and minwidth
+    // this seems to produce to the pixel exaxt results with IE. Wonder is some of this also holds for width distributing.
+    if ( available < 0 ) {
+	int mw = 0;
+	for ( int i = nEffCols-1; i >= 0; i-- )
+	    mw += layoutStruct[i].calcWidth - layoutStruct[i].effMinWidth;
+	for ( int i = nEffCols-1; i >= 0 && mw > 0; i-- ) {
+	    int minMaxDiff = layoutStruct[i].calcWidth-layoutStruct[i].effMinWidth;
+	    int reduce = available * minMaxDiff / mw;
+	    layoutStruct[i].calcWidth += reduce;
+	    available -= reduce;
+	    mw -= minMaxDiff;
+	    if ( available >= 0 )
+		break;
+	}
+    }
+
+    //qDebug( "    final available=%d", available );
+
+    int pos = 0;
+    for ( int i = 0; i < nEffCols; i++ ) {
+#ifdef DEBUG_LAYOUT
+	qDebug("col %d: %d (width %d)", i, pos, layoutStruct[i].calcWidth );
+#endif
+	table->columnPos[i] = pos;
+	pos += layoutStruct[i].calcWidth + table->cellSpacing();
+    }
+    table->columnPos[table->columnPos.size()-1] = pos;
+
+}
+
+
+void AutoTableLayout::calcPercentages() const
+{
+    total_percent = 0;
+    for ( unsigned int i = 0; i < layoutStruct.size(); i++ ) {
+	if ( layoutStruct[i].width.type == Percent )
+	    total_percent += layoutStruct[i].width.value;
+    }
+    percentagesDirty = false;
+}
+
+#undef DEBUG_LAYOUT
diff --git a/WebCore/khtml/rendering/table_layout.h b/WebCore/khtml/rendering/table_layout.h
new file mode 100644
index 0000000..7fdae35
--- /dev/null
+++ b/WebCore/khtml/rendering/table_layout.h
@@ -0,0 +1,113 @@
+/*
+ * This file is part of the HTML rendering engine for KDE.
+ *
+ * Copyright (C) 2002 Lars Knoll (knoll at kde.org)
+ *           (C) 2002 Dirk Mueller (mueller at kde.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+#ifndef TABLE_LAYOUT_H
+#define TABLE_LAYOUT_H
+
+#include <qmemarray.h>
+#include <misc/khtmllayout.h>
+
+namespace khtml {
+
+class RenderTable;
+class RenderTableCell;
+
+// -------------------------------------------------------------------------
+
+class TableLayout
+{
+public:
+    TableLayout( RenderTable *t ) : table( t ) {}
+    virtual ~TableLayout() {};
+
+    virtual void calcMinMaxWidth() = 0;
+    virtual void layout() = 0;
+
+protected:
+    RenderTable *table;
+};
+
+// -------------------------------------------------------------------------
+
+class FixedTableLayout : public TableLayout
+{
+public:
+    FixedTableLayout( RenderTable *table );
+    ~FixedTableLayout();
+
+    void calcMinMaxWidth();
+    void layout();
+
+protected:
+    int calcWidthArray( int tableWidth );
+
+    QMemArray<Length> width;
+};
+
+// -------------------------------------------------------------------------
+
+class AutoTableLayout : public TableLayout
+{
+public:
+    AutoTableLayout( RenderTable *table );
+    ~AutoTableLayout();
+
+    void calcMinMaxWidth();
+    void layout();
+
+
+protected:
+    void fullRecalc();
+    void recalcColumn( int effCol );
+    int totalPercent() const {
+	if ( percentagesDirty )
+	    calcPercentages();
+	return total_percent;
+    }
+    void calcPercentages() const;
+    int calcEffectiveWidth();
+    void insertSpanCell( RenderTableCell *cell );
+
+    struct Layout {
+	Layout() : minWidth( 1 ), maxWidth( 1 ),
+		   effMinWidth( 0 ), effMaxWidth( 0 ),
+		   calcWidth( 0 ) {}
+	Length width;
+	Length effWidth;
+	short minWidth;
+	short maxWidth;
+	short effMinWidth;
+	short effMaxWidth;
+	short calcWidth;
+    };
+
+    QMemArray<Layout> layoutStruct;
+    QMemArray<RenderTableCell *>spanCells;
+    bool hasPercent : 1;
+    mutable bool percentagesDirty : 1;
+    mutable bool effWidthDirty : 1;
+    mutable unsigned short total_percent;
+};
+
+};
+#endif
diff --git a/WebCore/khtml/xml/dom_docimpl.cpp b/WebCore/khtml/xml/dom_docimpl.cpp
index 85b2730..6123ff5 100644
--- a/WebCore/khtml/xml/dom_docimpl.cpp
+++ b/WebCore/khtml/xml/dom_docimpl.cpp
@@ -763,7 +763,7 @@ ElementImpl *DocumentImpl::createHTMLElement( const DOMString &name )
     case ID_THEAD:
     case ID_TBODY:
     case ID_TFOOT:
-        n = new HTMLTableSectionElementImpl(docPtr(), id);
+        n = new HTMLTableSectionElementImpl(docPtr(), id, false);
         break;
 
 // inline elements
diff --git a/WebCore/khtml/xml/dom_nodeimpl.cpp b/WebCore/khtml/xml/dom_nodeimpl.cpp
index f2f2db3..8ead729 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.cpp
+++ b/WebCore/khtml/xml/dom_nodeimpl.cpp
@@ -68,6 +68,7 @@ NodeImpl::NodeImpl(DocumentPtr *doc)
       m_focused( false ),
       m_active( false ),
       m_styleElement( false ),
+      m_implicit( false ),
       m_rendererNeedsClose( false )
 {
     if (document)
@@ -900,6 +901,7 @@ void NodeImpl::dump(QTextStream *stream, QString ind) const
     if (m_focused) { *stream << " focused"; }
     if (m_active) { *stream << " active"; }
     if (m_styleElement) { *stream << " styleElement"; }
+    if (m_implicit) { *stream << " implicit"; }
 
     *stream << " tabIndex=" << m_tabIndex;
     if (m_regdListeners)
diff --git a/WebCore/khtml/xml/dom_nodeimpl.h b/WebCore/khtml/xml/dom_nodeimpl.h
index 1dd9231..2e4be78 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.h
+++ b/WebCore/khtml/xml/dom_nodeimpl.h
@@ -186,6 +186,7 @@ public:
     bool hasAnchor() const { return m_hasAnchor; }
     bool inDocument() const { return m_inDocument; }
     bool styleElement() const { return m_styleElement; }
+    bool implicitNode() const { return m_implicit; }
     void setHasID(bool b=true) { m_hasId = b; }
     void setHasClass(bool b=true) { m_hasClass = b; }
     void setHasStyle(bool b=true) { m_hasStyle = b; }
@@ -395,9 +396,10 @@ protected:
     bool m_focused : 1;
     bool m_active : 1;
     bool m_styleElement : 1; // contains stylesheet text
+    bool m_implicit : 1; // implicitely generated by the parser
     bool m_rendererNeedsClose : 1;
 
-    // 2 bits unused
+    // 1 bit unused
 };
 
 // this is the full Node Implementation with parents and children.

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list