Changeset 3351 in webkit


Ignore:
Timestamp:
Jan 17, 2003, 2:42:07 PM (22 years ago)
Author:
hyatt
Message:

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:
Location:
trunk/WebCore
Files:
3 added
35 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog-2003-10-25

    r3350 r3351  
     12003-01-17  David Hyatt  <hyatt@apple.com>
     2
     3        The new table code from Lars.  Also includes bug fixes for
     4        percentage height children in table cells, for positioning
     5        of tables, and for width distribution of percentage width
     6        cells.
     7       
     8        Reviewed by darin
     9
     10        * ForwardingHeaders/rendering/table_layout.h: Added.
     11        * WebCore.pbproj/project.pbxproj:
     12        * khtml/css/cssparser.cpp:
     13        (StyleBaseImpl::parseValue):
     14        * khtml/css/cssstyleselector.cpp:
     15        * khtml/css/cssvalues.c:
     16        (findValue):
     17        * khtml/css/cssvalues.h:
     18        * khtml/css/cssvalues.in:
     19        * khtml/css/html4.css:
     20        * khtml/dom/html_table.cpp:
     21        (HTMLTableElement::insertRow):
     22        (HTMLTableElement::deleteRow):
     23        (HTMLTableRowElement::insertCell):
     24        (HTMLTableRowElement::deleteCell):
     25        (HTMLTableSectionElement::insertRow):
     26        (HTMLTableSectionElement::deleteRow):
     27        * khtml/html/html_tableimpl.cpp:
     28        (HTMLTableElementImpl::HTMLTableElementImpl):
     29        (HTMLTableElementImpl::setTFoot):
     30        (HTMLTableElementImpl::setTBody):
     31        (HTMLTableElementImpl::createTHead):
     32        (HTMLTableElementImpl::createTFoot):
     33        (HTMLTableElementImpl::insertRow):
     34        (HTMLTableElementImpl::deleteRow):
     35        (HTMLTableElementImpl::addChild):
     36        (HTMLTableElementImpl::parseAttribute):
     37        (HTMLTableElementImpl::attach):
     38        (HTMLTablePartElementImpl::parseAttribute):
     39        (HTMLTableSectionElementImpl::HTMLTableSectionElementImpl):
     40        (HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl):
     41        (HTMLTableSectionElementImpl::insertRow):
     42        (HTMLTableSectionElementImpl::deleteRow):
     43        (HTMLTableSectionElementImpl::numRows):
     44        (HTMLTableRowElementImpl::rowIndex):
     45        (HTMLTableRowElementImpl::insertCell):
     46        (HTMLTableRowElementImpl::deleteCell):
     47        (HTMLTableCellElementImpl::HTMLTableCellElementImpl):
     48        (HTMLTableCellElementImpl::parseAttribute):
     49        (HTMLTableCellElementImpl::attach):
     50        (HTMLTableColElementImpl::HTMLTableColElementImpl):
     51        (HTMLTableColElementImpl::parseAttribute):
     52        * khtml/html/html_tableimpl.h:
     53        * khtml/html/htmlparser.cpp:
     54        (KHTMLParser::insertNode):
     55        (KHTMLParser::getElement):
     56        * khtml/rendering/bidi.cpp:
     57        (RenderFlow::layoutInlineChildren):
     58        * khtml/rendering/render_body.cpp:
     59        (RenderBody::availableHeight):
     60        * khtml/rendering/render_body.h:
     61        * khtml/rendering/render_box.cpp:
     62        (RenderBox::contentWidth):
     63        (RenderBox::contentHeight):
     64        (RenderBox::calcReplacedWidth):
     65        (RenderBox::calcReplacedHeight):
     66        (RenderBox::availableHeight):
     67        (RenderBox::calcAbsoluteVertical):
     68        * khtml/rendering/render_box.h:
     69        * khtml/rendering/render_flow.cpp:
     70        (RenderFlow::layoutBlockChildren):
     71        (RenderFlow::leftOffset):
     72        (RenderFlow::rightOffset):
     73        (RenderFlow::addOverHangingFloats):
     74        (RenderFlow::calcBlockMinMaxWidth):
     75        (RenderFlow::calcMinMaxWidth):
     76        * khtml/rendering/render_form.cpp:
     77        * khtml/rendering/render_form.h:
     78        * khtml/rendering/render_frames.cpp:
     79        * khtml/rendering/render_frames.h:
     80        * khtml/rendering/render_object.cpp:
     81        (RenderObject::createObject):
     82        (RenderObject::paddingTop):
     83        (RenderObject::paddingBottom):
     84        (RenderObject::paddingLeft):
     85        (RenderObject::paddingRight):
     86        * khtml/rendering/render_object.h:
     87        * khtml/rendering/render_replaced.cpp:
     88        (RenderReplaced::calcMinMaxWidth):
     89        * khtml/rendering/render_root.cpp:
     90        (RenderRoot::RenderRoot):
     91        (RenderRoot::layout):
     92        (RenderRoot::paintObject):
     93        * khtml/rendering/render_root.h:
     94        * khtml/rendering/render_style.cpp:
     95        (StyleSurroundData::StyleSurroundData):
     96        * khtml/rendering/render_style.h:
     97        * khtml/rendering/render_table.cpp:
     98        (RenderTable::RenderTable):
     99        (RenderTable::~RenderTable):
     100        (RenderTable::setStyle):
     101        (RenderTable::position):
     102        (RenderTable::addChild):
     103        (RenderTable::calcWidth):
     104        (RenderTable::layout):
     105        (RenderTable::setCellWidths):
     106        (RenderTable::paint):
     107        (RenderTable::calcMinMaxWidth):
     108        (RenderTable::splitColumn):
     109        (RenderTable::appendColumn):
     110        (RenderTable::colElement):
     111        (RenderTable::recalcSections):
     112        (RenderTable::removeChildNode):
     113        (RenderTable::dump):
     114        (RenderTableSection::RenderTableSection):
     115        (RenderTableSection::~RenderTableSection):
     116        (RenderTableSection::detach):
     117        (RenderTableSection::setStyle):
     118        (RenderTableSection::addChild):
     119        (RenderTableSection::ensureRows):
     120        (RenderTableSection::addCell):
     121        (RenderTableSection::setCellWidths):
     122        (RenderTableSection::calcRowHeight):
     123        (RenderTableSection::layoutRows):
     124        (RenderTableSection::paint):
     125        (RenderTableSection::recalcCells):
     126        (RenderTableSection::clearGrid):
     127        (RenderTableSection::removeChildNode):
     128        (RenderTableSection::dump):
     129        (RenderTableRow::RenderTableRow):
     130        (RenderTableRow::detach):
     131        (RenderTableRow::setStyle):
     132        (RenderTableRow::addChild):
     133        (RenderTableRow::removeChildNode):
     134        (RenderTableRow::dump):
     135        (RenderTableRow::layout):
     136        (RenderTableCell::RenderTableCell):
     137        (RenderTableCell::detach):
     138        (RenderTableCell::updateFromElement):
     139        (RenderTableCell::getCellPercentageHeight):
     140        (RenderTableCell::setCellPercentageHeight):
     141        (RenderTableCell::calcMinMaxWidth):
     142        (RenderTableCell::baselinePosition):
     143        (RenderTableCell::setStyle):
     144        (RenderTableCell::paint):
     145        (RenderTableCell::paintBoxDecorations):
     146        (RenderTableCell::dump):
     147        (RenderTableCol::RenderTableCol):
     148        (RenderTableCol::updateFromElement):
     149        (RenderTableCol::addChild):
     150        (RenderTableCol::dump):
     151        * khtml/rendering/render_table.h:
     152        * khtml/rendering/table_layout.cpp: Added.
     153        (FixedTableLayout::FixedTableLayout):
     154        (FixedTableLayout::~FixedTableLayout):
     155        (FixedTableLayout::calcWidthArray):
     156        (FixedTableLayout::calcMinMaxWidth):
     157        (FixedTableLayout::layout):
     158        (AutoTableLayout::AutoTableLayout):
     159        (AutoTableLayout::~AutoTableLayout):
     160        (AutoTableLayout::recalcColumn):
     161        (AutoTableLayout::fullRecalc):
     162        (AutoTableLayout::calcMinMaxWidth):
     163        (AutoTableLayout::calcEffectiveWidth):
     164        (AutoTableLayout::insertSpanCell):
     165        (AutoTableLayout::layout):
     166        (AutoTableLayout::calcPercentages):
     167        * khtml/rendering/table_layout.h: Added.
     168        * khtml/xml/dom_docimpl.cpp:
     169        (DocumentImpl::createHTMLElement):
     170        * khtml/xml/dom_nodeimpl.cpp:
     171        (NodeImpl::NodeImpl):
     172        (NodeImpl::dump):
     173        * khtml/xml/dom_nodeimpl.h:
     174
    11752003-01-17  Darin Adler  <darin@apple.com>
    2176
  • trunk/WebCore/ChangeLog-2005-08-23

    r3350 r3351  
     12003-01-17  David Hyatt  <hyatt@apple.com>
     2
     3        The new table code from Lars.  Also includes bug fixes for
     4        percentage height children in table cells, for positioning
     5        of tables, and for width distribution of percentage width
     6        cells.
     7       
     8        Reviewed by darin
     9
     10        * ForwardingHeaders/rendering/table_layout.h: Added.
     11        * WebCore.pbproj/project.pbxproj:
     12        * khtml/css/cssparser.cpp:
     13        (StyleBaseImpl::parseValue):
     14        * khtml/css/cssstyleselector.cpp:
     15        * khtml/css/cssvalues.c:
     16        (findValue):
     17        * khtml/css/cssvalues.h:
     18        * khtml/css/cssvalues.in:
     19        * khtml/css/html4.css:
     20        * khtml/dom/html_table.cpp:
     21        (HTMLTableElement::insertRow):
     22        (HTMLTableElement::deleteRow):
     23        (HTMLTableRowElement::insertCell):
     24        (HTMLTableRowElement::deleteCell):
     25        (HTMLTableSectionElement::insertRow):
     26        (HTMLTableSectionElement::deleteRow):
     27        * khtml/html/html_tableimpl.cpp:
     28        (HTMLTableElementImpl::HTMLTableElementImpl):
     29        (HTMLTableElementImpl::setTFoot):
     30        (HTMLTableElementImpl::setTBody):
     31        (HTMLTableElementImpl::createTHead):
     32        (HTMLTableElementImpl::createTFoot):
     33        (HTMLTableElementImpl::insertRow):
     34        (HTMLTableElementImpl::deleteRow):
     35        (HTMLTableElementImpl::addChild):
     36        (HTMLTableElementImpl::parseAttribute):
     37        (HTMLTableElementImpl::attach):
     38        (HTMLTablePartElementImpl::parseAttribute):
     39        (HTMLTableSectionElementImpl::HTMLTableSectionElementImpl):
     40        (HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl):
     41        (HTMLTableSectionElementImpl::insertRow):
     42        (HTMLTableSectionElementImpl::deleteRow):
     43        (HTMLTableSectionElementImpl::numRows):
     44        (HTMLTableRowElementImpl::rowIndex):
     45        (HTMLTableRowElementImpl::insertCell):
     46        (HTMLTableRowElementImpl::deleteCell):
     47        (HTMLTableCellElementImpl::HTMLTableCellElementImpl):
     48        (HTMLTableCellElementImpl::parseAttribute):
     49        (HTMLTableCellElementImpl::attach):
     50        (HTMLTableColElementImpl::HTMLTableColElementImpl):
     51        (HTMLTableColElementImpl::parseAttribute):
     52        * khtml/html/html_tableimpl.h:
     53        * khtml/html/htmlparser.cpp:
     54        (KHTMLParser::insertNode):
     55        (KHTMLParser::getElement):
     56        * khtml/rendering/bidi.cpp:
     57        (RenderFlow::layoutInlineChildren):
     58        * khtml/rendering/render_body.cpp:
     59        (RenderBody::availableHeight):
     60        * khtml/rendering/render_body.h:
     61        * khtml/rendering/render_box.cpp:
     62        (RenderBox::contentWidth):
     63        (RenderBox::contentHeight):
     64        (RenderBox::calcReplacedWidth):
     65        (RenderBox::calcReplacedHeight):
     66        (RenderBox::availableHeight):
     67        (RenderBox::calcAbsoluteVertical):
     68        * khtml/rendering/render_box.h:
     69        * khtml/rendering/render_flow.cpp:
     70        (RenderFlow::layoutBlockChildren):
     71        (RenderFlow::leftOffset):
     72        (RenderFlow::rightOffset):
     73        (RenderFlow::addOverHangingFloats):
     74        (RenderFlow::calcBlockMinMaxWidth):
     75        (RenderFlow::calcMinMaxWidth):
     76        * khtml/rendering/render_form.cpp:
     77        * khtml/rendering/render_form.h:
     78        * khtml/rendering/render_frames.cpp:
     79        * khtml/rendering/render_frames.h:
     80        * khtml/rendering/render_object.cpp:
     81        (RenderObject::createObject):
     82        (RenderObject::paddingTop):
     83        (RenderObject::paddingBottom):
     84        (RenderObject::paddingLeft):
     85        (RenderObject::paddingRight):
     86        * khtml/rendering/render_object.h:
     87        * khtml/rendering/render_replaced.cpp:
     88        (RenderReplaced::calcMinMaxWidth):
     89        * khtml/rendering/render_root.cpp:
     90        (RenderRoot::RenderRoot):
     91        (RenderRoot::layout):
     92        (RenderRoot::paintObject):
     93        * khtml/rendering/render_root.h:
     94        * khtml/rendering/render_style.cpp:
     95        (StyleSurroundData::StyleSurroundData):
     96        * khtml/rendering/render_style.h:
     97        * khtml/rendering/render_table.cpp:
     98        (RenderTable::RenderTable):
     99        (RenderTable::~RenderTable):
     100        (RenderTable::setStyle):
     101        (RenderTable::position):
     102        (RenderTable::addChild):
     103        (RenderTable::calcWidth):
     104        (RenderTable::layout):
     105        (RenderTable::setCellWidths):
     106        (RenderTable::paint):
     107        (RenderTable::calcMinMaxWidth):
     108        (RenderTable::splitColumn):
     109        (RenderTable::appendColumn):
     110        (RenderTable::colElement):
     111        (RenderTable::recalcSections):
     112        (RenderTable::removeChildNode):
     113        (RenderTable::dump):
     114        (RenderTableSection::RenderTableSection):
     115        (RenderTableSection::~RenderTableSection):
     116        (RenderTableSection::detach):
     117        (RenderTableSection::setStyle):
     118        (RenderTableSection::addChild):
     119        (RenderTableSection::ensureRows):
     120        (RenderTableSection::addCell):
     121        (RenderTableSection::setCellWidths):
     122        (RenderTableSection::calcRowHeight):
     123        (RenderTableSection::layoutRows):
     124        (RenderTableSection::paint):
     125        (RenderTableSection::recalcCells):
     126        (RenderTableSection::clearGrid):
     127        (RenderTableSection::removeChildNode):
     128        (RenderTableSection::dump):
     129        (RenderTableRow::RenderTableRow):
     130        (RenderTableRow::detach):
     131        (RenderTableRow::setStyle):
     132        (RenderTableRow::addChild):
     133        (RenderTableRow::removeChildNode):
     134        (RenderTableRow::dump):
     135        (RenderTableRow::layout):
     136        (RenderTableCell::RenderTableCell):
     137        (RenderTableCell::detach):
     138        (RenderTableCell::updateFromElement):
     139        (RenderTableCell::getCellPercentageHeight):
     140        (RenderTableCell::setCellPercentageHeight):
     141        (RenderTableCell::calcMinMaxWidth):
     142        (RenderTableCell::baselinePosition):
     143        (RenderTableCell::setStyle):
     144        (RenderTableCell::paint):
     145        (RenderTableCell::paintBoxDecorations):
     146        (RenderTableCell::dump):
     147        (RenderTableCol::RenderTableCol):
     148        (RenderTableCol::updateFromElement):
     149        (RenderTableCol::addChild):
     150        (RenderTableCol::dump):
     151        * khtml/rendering/render_table.h:
     152        * khtml/rendering/table_layout.cpp: Added.
     153        (FixedTableLayout::FixedTableLayout):
     154        (FixedTableLayout::~FixedTableLayout):
     155        (FixedTableLayout::calcWidthArray):
     156        (FixedTableLayout::calcMinMaxWidth):
     157        (FixedTableLayout::layout):
     158        (AutoTableLayout::AutoTableLayout):
     159        (AutoTableLayout::~AutoTableLayout):
     160        (AutoTableLayout::recalcColumn):
     161        (AutoTableLayout::fullRecalc):
     162        (AutoTableLayout::calcMinMaxWidth):
     163        (AutoTableLayout::calcEffectiveWidth):
     164        (AutoTableLayout::insertSpanCell):
     165        (AutoTableLayout::layout):
     166        (AutoTableLayout::calcPercentages):
     167        * khtml/rendering/table_layout.h: Added.
     168        * khtml/xml/dom_docimpl.cpp:
     169        (DocumentImpl::createHTMLElement):
     170        * khtml/xml/dom_nodeimpl.cpp:
     171        (NodeImpl::NodeImpl):
     172        (NodeImpl::dump):
     173        * khtml/xml/dom_nodeimpl.h:
     174
    11752003-01-17  Darin Adler  <darin@apple.com>
    2176
  • trunk/WebCore/WebCore.pbproj/project.pbxproj

    r3348 r3351  
    176176</plist>
    177177";
     178                        shouldUseHeadermap = 0;
    178179                };
    179180                0867D69DFE84028FC02AAC07 = {
     
    479480                                93F12CB303CCFD570000011C,
    480481                                93F12CC803CD0AE60000011C,
     482                                BCF0192703D3802200B2D04D,
    481483                                931BFCD003D4AEDA008635CE,
    482484                                931BFCD403D4AEE5008635CE,
     
    719721                                93F12CAE03CCFD570000011C,
    720722                                93F12CB003CCFD570000011C,
     723                                BCF0192603D3802200B2D04D,
    721724                                931BFCD103D4AEDA008635CE,
    722725                                931BFCD503D4AEE5008635CE,
     
    14531456                BC7294FE03804B5600A80166 = {
    14541457                        fileRef = BC7294FC03804B5600A80166;
     1458                        isa = PBXBuildFile;
     1459                        settings = {
     1460                        };
     1461                };
     1462                BCF0192403D3802200B2D04D = {
     1463                        fileEncoding = 30;
     1464                        isa = PBXFileReference;
     1465                        path = table_layout.cpp;
     1466                        refType = 4;
     1467                };
     1468                BCF0192503D3802200B2D04D = {
     1469                        fileEncoding = 30;
     1470                        isa = PBXFileReference;
     1471                        path = table_layout.h;
     1472                        refType = 4;
     1473                };
     1474                BCF0192603D3802200B2D04D = {
     1475                        fileRef = BCF0192403D3802200B2D04D;
     1476                        isa = PBXBuildFile;
     1477                        settings = {
     1478                        };
     1479                };
     1480                BCF0192703D3802200B2D04D = {
     1481                        fileRef = BCF0192503D3802200B2D04D;
    14551482                        isa = PBXBuildFile;
    14561483                        settings = {
     
    41694196                                F523D2C702DE4438018635CA,
    41704197                                F523D2C602DE4438018635CA,
     4198                                BC7294FB03804B5600A80166,
     4199                                BC7294FC03804B5600A80166,
     4200                                BCF0192403D3802200B2D04D,
     4201                                BCF0192503D3802200B2D04D,
    41714202                        );
    41724203                        isa = PBXGroup;
  • trunk/WebCore/khtml/css/cssparser.cpp

    r3098 r3351  
    11991199
    12001200      case CSS_PROP_UNICODE_BIDI:         // normal | embed | bidi-override | inherit
    1201       case CSS_PROP_WHITE_SPACE:          // normal | pre | nowrap | inherit
     1201      case CSS_PROP_WHITE_SPACE:          // normal | pre | nowrap | -konq-nowrap | inherit
    12021202      case CSS_PROP_FONT_STRETCH:
    12031203        // normal | wider | narrower | ultra-condensed | extra-condensed | condensed |
  • trunk/WebCore/khtml/css/cssstyleselector.cpp

    r3304 r3351  
    17441744        EWhiteSpace s;
    17451745        switch(primitiveValue->getIdent()) {
     1746        case CSS_VAL__KONQ_NOWRAP:
     1747            s = KONQ_NOWRAP;
     1748            break;
    17461749        case CSS_VAL_NOWRAP:
    17471750            s = NOWRAP;
  • trunk/WebCore/khtml/css/cssvalues.c

    r2831 r3351  
    109109  enum
    110110    {
    111       TOTAL_KEYWORDS = 180,
     111      TOTAL_KEYWORDS = 181,
    112112      MIN_WORD_LENGTH = 3,
    113113      MAX_WORD_LENGTH = 21,
     
    281281      {"higher", CSS_VAL_HIGHER},
    282282      {"table-column", CSS_VAL_TABLE_COLUMN},
     283      {"-konq-nowrap", CSS_VAL__KONQ_NOWRAP},
    283284      {"message-box", CSS_VAL_MESSAGE_BOX},
    284285      {"ultra-condensed", CSS_VAL_ULTRA_CONDENSED},
     
    317318        -1,   -1,   -1,   -1,   -1,   18,   -1,   -1,
    318319        -1,   -1,   -1,   -1,   -1,   -1,   -1,   19,
    319       -302, -160,   -2,   22,   -1,   -1,   -1,   -1,
     320      -303, -161,   -2,   22,   -1,   -1,   -1,   -1,
    320321        -1,   -1,   23,   -1,   -1,   24,   -1,   -1,
    321322        -1,   -1,   -1,   -1,   25,   -1,   -1,   26,
     
    393394        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    394395        -1,   -1,  162,   -1,   -1,   -1,   -1,   -1,
    395         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    396         -1,   -1,  163,   -1,   -1,   -1,   -1,   -1,
    397         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    398         -1,   -1,   -1,   -1,   -1,  164,   -1,   -1,
    399         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    400         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    401         -1,   -1,   -1,   -1,  165,   -1,   -1,   -1,
    402         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    403         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    404         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    405         -1,   -1,   -1,   -1,   -1,  166,   -1,   -1,
    406         -1,   -1,   -1,   -1,  167,   -1,   -1,   -1,
    407         -1,  168,   -1,   -1,   -1,   -1,   -1,  169,
    408         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    409         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    410         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    411         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    412         -1,   -1,   -1,   -1,   -1,   -1,  170,   -1,
    413         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    414         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    415         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    416         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    417         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    418         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    419         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    420         -1,   -1,   -1,   -1,   -1,   -1,   -1,  171,
    421         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    422         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    423         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    424         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    425         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    426         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    427         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    428         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    429         -1,   -1,   -1,   -1,  172,   -1,   -1,   -1,
     396        -1,  163,   -1,   -1,   -1,   -1,   -1,   -1,
     397        -1,   -1,  164,   -1,   -1,   -1,   -1,   -1,
     398        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     399        -1,   -1,   -1,   -1,   -1,  165,   -1,   -1,
     400        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     401        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     402        -1,   -1,   -1,   -1,  166,   -1,   -1,   -1,
     403        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     404        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     405        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     406        -1,   -1,   -1,   -1,   -1,  167,   -1,   -1,
     407        -1,   -1,   -1,   -1,  168,   -1,   -1,   -1,
     408        -1,  169,   -1,   -1,   -1,   -1,   -1,  170,
     409        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     410        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     411        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     412        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     413        -1,   -1,   -1,   -1,   -1,   -1,  171,   -1,
     414        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     415        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     416        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     417        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     418        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     419        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     420        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     421        -1,   -1,   -1,   -1,   -1,   -1,   -1,  172,
     422        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     423        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     424        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     425        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     426        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     427        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     428        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     429        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    430430        -1,   -1,   -1,   -1,  173,   -1,   -1,   -1,
    431         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    432         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    433         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    434         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    435         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    436         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    437         -1,   -1,   -1,   -1,   -1,   -1,  174,   -1,
    438         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    439         -1,   -1,  175,   -1,   -1,   -1,   -1,   -1,
    440         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     431        -1,   -1,   -1,   -1,  174,   -1,   -1,   -1,
     432        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     433        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     434        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     435        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     436        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     437        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     438        -1,   -1,   -1,   -1,   -1,   -1,  175,   -1,
    441439        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    442440        -1,   -1,  176,   -1,   -1,   -1,   -1,   -1,
    443        177,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    444         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    445         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    446         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    447         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    448         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    449         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    450         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    451         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    452         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    453         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    454         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    455         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    456         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    457         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    458         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    459         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    460         -1,   -1,   -1,  178,   -1,   -1,   -1,   -1,
    461         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    462         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    463         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    464         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    465         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    466         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    467         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    468         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    469         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    470         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    471         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    472         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    473         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    474         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    475         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    476         -1,   -1,   -1,   -1,   -1,  179
     441        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     442        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     443        -1,   -1,  177,   -1,   -1,   -1,   -1,   -1,
     444       178,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     445        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     446        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     447        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     448        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     449        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     450        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     451        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     452        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     453        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     454        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     455        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     456        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     457        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     458        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     459        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     460        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     461        -1,   -1,   -1,  179,   -1,   -1,   -1,   -1,
     462        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     463        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     464        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     465        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     466        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     467        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     468        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     469        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     470        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     471        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     472        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     473        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     474        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     475        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     476        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
     477        -1,   -1,   -1,   -1,   -1,  180
    477478    };
    478479
     
    691692"thin",
    692693"underline",
     694"-konq-nowrap",
    693695"-konq-normal",
    694696"-konq-around-floats",
  • trunk/WebCore/khtml/css/cssvalues.h

    r2831 r3351  
    188188#define CSS_VAL_THIN 177
    189189#define CSS_VAL_UNDERLINE 178
    190 #define CSS_VAL__KONQ_NORMAL 179
    191 #define CSS_VAL__KONQ_AROUND_FLOATS 180
     190#define CSS_VAL__KONQ_NOWRAP 179
     191#define CSS_VAL__KONQ_NORMAL 180
     192#define CSS_VAL__KONQ_AROUND_FLOATS 181
    192193
    193 #define CSS_VAL_TOTAL 181
     194#define CSS_VAL_TOTAL 182
    194195#endif
    195196
  • trunk/WebCore/khtml/css/cssvalues.in

    r1024 r3351  
    259259thin
    260260underline
     261-konq-nowrap
    261262# CSS_PROP__KONQ_FLOW_MODE
    262263-konq-normal
  • trunk/WebCore/khtml/css/html4.css

    r3285 r3351  
    188188        border-spacing: 2px;
    189189        border-color: gray;
    190         padding: 1px;
    191         -konq-flow-mode: -konq-around-floats;
     190    -konq-flow-mode: -konq-around-floats;
    192191}
    193192
     
    208207        display: table-header-group;
    209208    vertical-align: middle;
    210         border: inherit;
     209    border-color: inherit;
    211210}
    212211     
     
    214213        display: table-row-group;
    215214    vertical-align: middle;
    216     border: inherit;
     215    border-color: inherit;
    217216}
    218217     
     
    220219        display: table-footer-group;
    221220    vertical-align: middle;
    222         border: inherit;
     221    border-color: inherit;
    223222}
    224223
  • trunk/WebCore/khtml/dom/html_table.cpp

    r1326 r3351  
    607607{
    608608    if(!impl) return 0;
    609     return ((HTMLTableElementImpl *)impl)->insertRow( index );
     609    int exceptioncode = 0;
     610    HTMLElementImpl* ret = ((HTMLTableElementImpl *)impl)->insertRow( index, exceptioncode );
     611    if (exceptioncode)
     612        throw DOMException(exceptioncode);
     613    return ret;
    610614}
    611615
    612616void HTMLTableElement::deleteRow( long index )
    613617{
    614     if(impl)
    615         ((HTMLTableElementImpl *)impl)->deleteRow( index );
     618    int exceptioncode = 0;
     619    if(impl)
     620        ((HTMLTableElementImpl *)impl)->deleteRow( index, exceptioncode );
     621    if (exceptioncode)
     622        throw DOMException(exceptioncode);
    616623}
    617624
     
    737744{
    738745    if(!impl) return 0;
    739     return ((HTMLTableRowElementImpl *)impl)->insertCell( index );
     746    int exceptioncode = 0;
     747    HTMLElementImpl* ret = ((HTMLTableRowElementImpl *)impl)->insertCell( index, exceptioncode );
     748    if (exceptioncode)
     749        throw DOMException(exceptioncode);
     750    return ret;
    740751}
    741752
    742753void HTMLTableRowElement::deleteCell( long index )
    743754{
    744     if(impl)
    745         ((HTMLTableRowElementImpl *)impl)->deleteCell( index );
     755    int exceptioncode = 0;
     756    if(impl)
     757        ((HTMLTableRowElementImpl *)impl)->deleteCell( index, exceptioncode );
     758    if (exceptioncode)
     759        throw DOMException(exceptioncode);
    746760}
    747761
     
    837851{
    838852    if(!impl) return 0;
    839     return ((HTMLTableSectionElementImpl *)impl)->insertRow( index );
     853    int exceptioncode = 0;
     854    HTMLElementImpl* ret = ((HTMLTableSectionElementImpl *)impl)->insertRow( index, exceptioncode );
     855    if (exceptioncode)
     856        throw DOMException(exceptioncode);
     857    return ret;
    840858}
    841859
    842860void HTMLTableSectionElement::deleteRow( long index )
    843861{
    844     if(impl)
    845         ((HTMLTableSectionElementImpl *)impl)->deleteRow( index );
    846 }
    847 
     862    int exceptioncode = 0;
     863    if(impl)
     864        ((HTMLTableSectionElementImpl *)impl)->deleteRow( index, exceptioncode );
     865    if (exceptioncode)
     866        throw DOMException(exceptioncode);
     867}
     868
  • trunk/WebCore/khtml/html/html_tableimpl.cpp

    r3098 r3351  
    4343
    4444#include <kdebug.h>
     45#include <kglobal.h>
    4546
    4647using namespace khtml;
     
    5556    firstBody = 0;
    5657
     58#if 0
    5759    rules = None;
    5860    frame = Void;
    59 
    60     m_cellPadding = -1;
     61#endif
     62    padding = 1;
    6163   
    62     incremental = false;
    6364    m_noBorder = true;
    6465    m_solid = false;
     
    7273{
    7374    return ID_TABLE;
    74 }
    75 
    76 void HTMLTableElementImpl::attach()
    77 {
    78     assert(!m_attached);
    79     if (parent()->renderer()) {
    80         // reset font color and sizes here, if we don't have strict parse mode.
    81         // this is 90% compatible to ie and mozilla, and the by way easiest solution...
    82         // only difference to 100% correct is that in strict mode <font> elements are propagated into tables.
    83         if ( getDocument()->parseMode() != DocumentImpl::Strict ) {
    84             addCSSProperty( CSS_PROP_FONT_SIZE, CSS_VAL_MEDIUM );
    85             addCSSProperty( CSS_PROP_COLOR, getDocument()->textColor() );
    86             addCSSProperty( CSS_PROP_FONT_FAMILY, "konq_body" );
    87         }
    88     }
    89 
    90     HTMLElementImpl::attach();
    91    
    92     if (m_render && m_render->isTable()) {
    93         RenderTable* table = static_cast<RenderTable*>(m_render);
    94         table->setCellPadding(m_cellPadding);
    95     }
    9675}
    9776
     
    136115        replaceChild ( s, foot, exceptioncode );
    137116        r = s;
    138     }
    139     else if( firstBody )
     117    } else if( firstBody )
    140118        r = insertBefore( s, firstBody, exceptioncode );
    141119    else
     
    150128    NodeImpl* r;
    151129
    152     if(!firstBody)
    153         firstBody = s;
    154 
    155     if( foot )
    156         r = insertBefore( s, foot, exceptioncode );
    157     else
     130    if(firstBody) {
     131        replaceChild ( s, firstBody, exceptioncode );
     132        r = s;
     133    } else
    158134        r = appendChild( s, exceptioncode );
     135    firstBody = s;
    159136
    160137    return r;
     
    166143    {
    167144        int exceptioncode = 0;
    168         head = new HTMLTableSectionElementImpl(docPtr(), ID_THEAD);
     145        head = new HTMLTableSectionElementImpl(docPtr(), ID_THEAD, true /* implicit */);
    169146        if(foot)
    170147            insertBefore( head, foot, exceptioncode );
    171         if(firstBody)
     148        else if(firstBody)
    172149            insertBefore( head, firstBody, exceptioncode);
    173150        else
     
    191168    {
    192169        int exceptioncode = 0;
    193         foot = new HTMLTableSectionElementImpl(docPtr(), ID_TFOOT);
     170        foot = new HTMLTableSectionElementImpl(docPtr(), ID_TFOOT, true /*implicit */);
    194171        if(firstBody)
    195172            insertBefore( foot, firstBody, exceptioncode );
     
    229206}
    230207
    231 HTMLElementImpl *HTMLTableElementImpl::insertRow( long index )
    232 {
     208HTMLElementImpl *HTMLTableElementImpl::insertRow( long index, int &exceptioncode )
     209{
     210    // The DOM requires that we create a tbody if the table is empty
     211    // (cf DOM2TS HTMLTableElement31 test)
     212    // (note: this is different from "if the table has no sections", since we can have
     213    // <TABLE><TR>)
     214    if(!firstBody && !head && !foot && !hasChildNodes())
     215        setTBody( new HTMLTableSectionElementImpl(docPtr(), ID_TBODY, true /* implicit */) );
     216
     217    //kdDebug(6030) << k_funcinfo << index << endl;
    233218    // IE treats index=-1 as default value meaning 'append after last'
    234219    // This isn't in the DOM. So, not implemented yet.
    235220    HTMLTableSectionElementImpl* section = 0L;
     221    HTMLTableSectionElementImpl* lastSection = 0L;
    236222    NodeImpl *node = firstChild();
    237     for ( ; node ; node = node->nextSibling() )
    238     {
    239         if ( node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY )
     223    bool append = (index == -1);
     224    bool found = false;
     225    for ( ; node && (index>=0 || append) ; node = node->nextSibling() )
     226    {
     227        // there could be 2 tfoot elements in the table. Only the first one is the "foot", that's why we have the more
     228        // complicated if statement below.
     229        if ( node != foot && (node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY) )
    240230        {
    241231            section = static_cast<HTMLTableSectionElementImpl *>(node);
    242             if ( section->numRows() > index )
    243                 break;
    244             else
    245                 index -= section->numRows();
    246         }
    247     }
    248     if (!section) {
    249         section = new HTMLTableSectionElementImpl(docPtr(), ID_TBODY);
    250         setTBody( section );
    251     }
    252     return section->insertRow( index );
    253 }
    254 
    255 void HTMLTableElementImpl::deleteRow( long index )
     232            lastSection = section;
     233            //kdDebug(6030) << k_funcinfo << "section id=" << node->id() << " rows:" << section->numRows() << endl;
     234            if ( !append )
     235            {
     236                int rows = section->numRows();
     237                if ( rows > index ) {
     238                    found = true;
     239                    break;
     240                } else
     241                    index -= rows;
     242                //kdDebug(6030) << "       index is now " << index << endl;
     243            }
     244        }
     245    }
     246    if ( !found && foot )
     247        section = static_cast<HTMLTableSectionElementImpl *>(foot);
     248
     249    // Index == 0 means "insert before first row in current section"
     250    // or "append after last row" (if there's no current section anymore)
     251    if ( !section && ( index == 0 || append ) )
     252    {
     253        section = lastSection;
     254        index = section ? section->numRows() : 0;
     255    }
     256    if ( section && (index >= 0 || append) ) {
     257        //kdDebug(6030) << "Inserting row into section " << section << " at index " << index << endl;
     258        return section->insertRow( index, exceptioncode );
     259    } else {
     260        // No more sections => index is too big
     261        exceptioncode = DOMException::INDEX_SIZE_ERR;
     262        return 0L;
     263    }
     264}
     265
     266void HTMLTableElementImpl::deleteRow( long index, int &exceptioncode )
    256267{
    257268    HTMLTableSectionElementImpl* section = 0L;
    258269    NodeImpl *node = firstChild();
     270    bool lastRow = index == -1;
     271    HTMLTableSectionElementImpl* lastSection = 0L;
     272    bool found = false;
    259273    for ( ; node ; node = node->nextSibling() )
    260274    {
    261         if ( node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY )
     275        if ( node != foot && (node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY) )
    262276        {
    263277            section = static_cast<HTMLTableSectionElementImpl *>(node);
    264             if ( section->numRows() > index )
    265                 break;
    266             else
    267                 index -= section->numRows();
    268         }
    269     }
    270     if ( section && index >= 0 && index < section->numRows() )
    271         section->deleteRow( index );
    272     // ## TODO error checking, returning exceptioncode
     278            lastSection = section;
     279            int rows = section->numRows();
     280            if ( !lastRow )
     281            {
     282                if ( rows > index ) {
     283                    found = true;
     284                    break;
     285                } else
     286                    index -= rows;
     287            }
     288        }
     289        section = 0L;
     290    }
     291    if ( !found && foot )
     292        section = static_cast<HTMLTableSectionElementImpl *>(foot);
     293
     294    if ( lastRow )
     295        lastSection->deleteRow( -1, exceptioncode );
     296    else if ( section && index >= 0 && index < section->numRows() )
     297        section->deleteRow( index, exceptioncode );
     298    else
     299        exceptioncode = DOMException::INDEX_SIZE_ERR;
    273300}
    274301
     
    279306#endif
    280307
    281     switch(child->id())
    282     {
    283     case ID_CAPTION:
    284         return setCaption(static_cast<HTMLTableCaptionElementImpl *>(child));
    285         break;
    286     case ID_COL:
    287     case ID_COLGROUP:
    288         {
    289         // these have to come before the table definition!
    290         if(head || foot || firstBody)
    291             return 0;
    292         HTMLElementImpl::addChild(child);
    293         // ###
    294         }
    295         return child;
    296     case ID_THEAD:
    297         //      if(incremental && !columnPos[totalCols]);// calcColWidth();
    298         return setTHead(static_cast<HTMLTableSectionElementImpl *>(child));
    299         break;
    300     case ID_TFOOT:
    301         //if(incremental && !columnPos[totalCols]);// calcColWidth();
    302         return setTFoot(static_cast<HTMLTableSectionElementImpl *>(child));
    303         break;
    304     case ID_TBODY:
    305         //if(incremental && !columnPos[totalCols]);// calcColWidth();
    306         return setTBody(static_cast<HTMLTableSectionElementImpl *>(child));
    307         break;
    308     case ID_FORM:
     308    if (child->id() == ID_FORM) {
    309309        // First add the child.
    310310        HTMLElementImpl::addChild(child);
     
    313313        return this;
    314314    }
    315     return 0;
     315   
     316    int exceptioncode = 0;
     317    NodeImpl *retval = appendChild( child, exceptioncode );
     318    if ( retval ) {
     319        switch(child->id()) {
     320        case ID_CAPTION:
     321            if ( !tCaption )
     322                tCaption = static_cast<HTMLTableCaptionElementImpl *>(child);
     323            break;
     324        case ID_COL:
     325        case ID_COLGROUP:
     326            break;
     327        case ID_THEAD:
     328            if ( !head )
     329                head = static_cast<HTMLTableSectionElementImpl *>(child);
     330            break;
     331        case ID_TFOOT:
     332            if ( !foot )
     333                foot = static_cast<HTMLTableSectionElementImpl *>(child);
     334            break;
     335        case ID_TBODY:
     336            if ( !firstBody )
     337                firstBody = static_cast<HTMLTableSectionElementImpl *>(child);
     338            break;
     339        }
     340    }
     341    return retval;
    316342}
    317343
     
    323349    case ATTR_WIDTH:
    324350        if (!attr->value().isEmpty())
    325             addCSSLength(CSS_PROP_WIDTH, attr->value());
     351            addCSSLength( CSS_PROP_WIDTH, attr->value() );
    326352        else
    327353            removeCSSProperty(CSS_PROP_WIDTH);
     
    430456    case ATTR_CELLPADDING:
    431457        if (!attr->value().isEmpty())
    432             m_cellPadding = attr->value().toInt();
    433         else
    434             m_cellPadding = -1;
    435         if (m_render && m_render->isTable()) {
    436             RenderTable* table = static_cast<RenderTable*>(m_render);
    437             table->setCellPadding(m_cellPadding);
    438         }
     458            padding = kMax( 0, attr->value().toInt() );
     459        else
     460            padding = 0;
    439461        break;
    440462    case ATTR_COLS:
     
    467489}
    468490
    469 void HTMLTableElementImpl::init()
    470 {
    471     HTMLElementImpl::init();
    472 
    473     if (!m_noBorder) {
    474         int v = m_solid ? CSS_VAL_SOLID : CSS_VAL_OUTSET;
    475         addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, v);
    476         addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v);
    477         addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, v);
    478         addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, v);
    479     }
     491void HTMLTableElementImpl::attach()
     492{
     493    assert(!m_attached);
     494    if (parent()->renderer()) {
     495        // reset font color and sizes here, if we don't have strict parse mode.
     496        // this is 90% compatible to ie and mozilla, and the by way easiest solution...
     497        // only difference to 100% correct is that in strict mode <font> elements are propagated into tables.
     498        if ( getDocument()->parseMode() != DocumentImpl::Strict ) {
     499            addCSSProperty( CSS_PROP_FONT_SIZE, CSS_VAL_MEDIUM );
     500            addCSSProperty( CSS_PROP_COLOR, getDocument()->textColor() );
     501            addCSSProperty( CSS_PROP_FONT_FAMILY, "konq_body" );
     502        }
     503       
     504        if (!m_noBorder) {
     505            int v = m_solid ? CSS_VAL_SOLID : CSS_VAL_OUTSET;
     506            addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, v);
     507            addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, v);
     508            addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, v);
     509            addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, v);
     510        }
     511    }
     512
     513    HTMLElementImpl::attach();
     514    if ( m_render && m_render->isTable() )
     515        static_cast<RenderTable *>(m_render)->setCellPadding( padding );
    480516}
    481517
     
    511547            addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID);
    512548            addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID);
    513             m_solid = true;
    514549        }
    515550        break;
     
    531566        break;
    532567    }
     568    case ATTR_HEIGHT:
     569        if (!attr->value().isEmpty())
     570            addCSSLength(CSS_PROP_HEIGHT, attr->value());
     571        else
     572            removeCSSProperty(CSS_PROP_HEIGHT);
     573        break;
    533574    case ATTR_NOSAVE:
    534575        break;
     
    541582
    542583HTMLTableSectionElementImpl::HTMLTableSectionElementImpl(DocumentPtr *doc,
    543                                                          ushort tagid)
     584                                                         ushort tagid, bool implicit)
    544585    : HTMLTablePartElementImpl(doc)
    545586{
    546587    _id = tagid;
     588    m_implicit = implicit;
    547589}
    548590
    549591HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl()
    550592{
    551     nrows = 0;
    552593}
    553594
     
    575616// these functions are rather slow, since we need to get the row at
    576617// the index... but they aren't used during usual HTML parsing anyway
    577 HTMLElementImpl *HTMLTableSectionElementImpl::insertRow( long index )
    578 {
    579     nrows++;
    580 
    581     HTMLTableRowElementImpl *r = new HTMLTableRowElementImpl(docPtr());
    582 
     618HTMLElementImpl *HTMLTableSectionElementImpl::insertRow( long index, int& exceptioncode )
     619{
     620    HTMLTableRowElementImpl *r = 0L;
    583621    NodeListImpl *children = childNodes();
    584     int exceptioncode = 0;
    585     if(!children || (int)children->length() <= index)
    586         appendChild(r, exceptioncode);
    587     else {
    588         NodeImpl *n;
    589         if(index < 1)
    590             n = firstChild();
    591         else
    592             n = children->item(index);
    593         insertBefore(r, n, exceptioncode );
    594     }
    595     if(children) delete children;
     622    int numRows = children ? (int)children->length() : 0;
     623    //kdDebug(6030) << k_funcinfo << "index=" << index << " numRows=" << numRows << endl;
     624    if ( index < -1 || index > numRows ) {
     625        exceptioncode = DOMException::INDEX_SIZE_ERR; // per the DOM
     626    }
     627    else
     628    {
     629        r = new HTMLTableRowElementImpl(docPtr());
     630        if ( numRows == index || index == -1 )
     631            appendChild(r, exceptioncode);
     632        else {
     633            NodeImpl *n;
     634            if(index < 1)
     635                n = firstChild();
     636            else
     637                n = children->item(index);
     638            insertBefore(r, n, exceptioncode );
     639        }
     640    }
     641    delete children;
    596642    return r;
    597643}
    598644
    599 void HTMLTableSectionElementImpl::deleteRow( long index )
    600 {
    601     if(index < 0) return;
     645void HTMLTableSectionElementImpl::deleteRow( long index, int &exceptioncode )
     646{
    602647    NodeListImpl *children = childNodes();
    603     if(children && (int)children->length() > index)
    604     {
    605         nrows--;
    606         int exceptioncode = 0;
     648    int numRows = children ? (int)children->length() : 0;
     649    if ( index == -1 ) index = numRows - 1;
     650    if( index >= 0 && index < numRows )
    607651        HTMLElementImpl::removeChild(children->item(index), exceptioncode);
    608     }
    609     if(children) delete children;
     652    else
     653        exceptioncode = DOMException::INDEX_SIZE_ERR;
     654    delete children;
     655}
     656
     657
     658int HTMLTableSectionElementImpl::numRows() const
     659{
     660    int rows = 0;
     661    const NodeImpl *n = firstChild();
     662    while (n) {
     663        if (n->id() == ID_TR)
     664            rows++;
     665        n = n->nextSibling();
     666    }
     667
     668    return rows;
    610669}
    611670
    612671// -------------------------------------------------------------------------
    613 
    614 HTMLTableRowElementImpl::HTMLTableRowElementImpl(DocumentPtr *doc)
    615   : HTMLTablePartElementImpl(doc)
    616 {
    617 }
    618 
    619 HTMLTableRowElementImpl::~HTMLTableRowElementImpl()
    620 {
    621 }
    622672
    623673NodeImpl::Id HTMLTableRowElementImpl::id() const
     
    644694long HTMLTableRowElementImpl::rowIndex() const
    645695{
    646     // some complex traversal stuff here to take into account that some rows may be in different sections
    647696    int rIndex = 0;
    648     const NodeImpl *n = this;
    649     do {
    650         while (!n->previousSibling() && !(n->isElementNode() && n->id() == ID_TABLE))
    651             n = n->parentNode();
    652         if (n->isElementNode() && n->id() == ID_TABLE)
    653             n = 0;
    654         if (n) {
    655             n = n->previousSibling();
    656             while (!(n->isElementNode() && n->id() == ID_TR) && n->lastChild())
    657                 n = n->lastChild();
    658         }
    659 
    660         if (n && n->isElementNode() && n->id() == ID_TR)
    661             rIndex++;
    662     }
    663     while (n && n->isElementNode() && n->id() == ID_TR);
    664 
    665     return rIndex;
     697
     698    NodeImpl *table = parentNode();
     699    if ( !table )
     700        return -1;
     701    table = table->parentNode();
     702    if ( !table || table->id() != ID_TABLE )
     703        return -1;
     704
     705    HTMLTableSectionElementImpl *foot = static_cast<HTMLTableElementImpl *>(table)->tFoot();
     706    NodeImpl *node = table->firstChild();
     707    while ( node ) {
     708        if ( node != foot && (node->id() == ID_THEAD || node->id() == ID_TFOOT || node->id() == ID_TBODY) ) {
     709            HTMLTableSectionElementImpl* section = static_cast<HTMLTableSectionElementImpl *>(node);
     710            const NodeImpl *row = section->firstChild();
     711            while ( row ) {
     712                if ( row == this )
     713                    return rIndex;
     714                rIndex++;
     715                row = row->nextSibling();
     716            }
     717        }
     718        node = node->nextSibling();
     719    }
     720    const NodeImpl *row = foot->firstChild();
     721    while ( row ) {
     722        if ( row == this )
     723            return rIndex;
     724        rIndex++;
     725        row = row->nextSibling();
     726    }
     727    // should never happen
     728    return -1;
    666729}
    667730
     
    680743}
    681744
    682 HTMLElementImpl *HTMLTableRowElementImpl::insertCell( long index )
    683 {
    684     HTMLTableCellElementImpl *c = new HTMLTableCellElementImpl(docPtr(), ID_TD);
    685 
     745HTMLElementImpl *HTMLTableRowElementImpl::insertCell( long index, int &exceptioncode )
     746{
     747    HTMLTableCellElementImpl *c = 0L;
    686748    NodeListImpl *children = childNodes();
    687     int exceptioncode = 0;
    688     if(!children || (int)children->length() <= index)
    689         appendChild(c, exceptioncode);
    690     else {
    691         NodeImpl *n;
    692         if(index < 1)
    693             n = firstChild();
    694         else
    695             n = children->item(index);
    696         insertBefore(c, n, exceptioncode);
    697     }
    698     if(children) delete children;
     749    int numCells = children ? children->length() : 0;
     750    if ( index < -1 || index > numCells )
     751        exceptioncode = DOMException::INDEX_SIZE_ERR; // per the DOM
     752    else
     753    {
     754        c = new HTMLTableCellElementImpl(docPtr(), ID_TD);
     755        if(numCells == index || index == -1)
     756            appendChild(c, exceptioncode);
     757        else {
     758            NodeImpl *n;
     759            if(index < 1)
     760                n = firstChild();
     761            else
     762                n = children->item(index);
     763            insertBefore(c, n, exceptioncode);
     764        }
     765    }
     766    delete children;
    699767    return c;
    700768}
    701769
    702 void HTMLTableRowElementImpl::deleteCell( long index )
    703 {
    704     if(index < 0) return;
     770void HTMLTableRowElementImpl::deleteCell( long index, int &exceptioncode )
     771{
    705772    NodeListImpl *children = childNodes();
    706     if(children && (int)children->length() > index) {
    707         int exceptioncode = 0;
     773    int numCells = children ? children->length() : 0;
     774    if ( index == -1 ) index = numCells-1;
     775    if( index >= 0 && index < numCells )
    708776        HTMLElementImpl::removeChild(children->item(index), exceptioncode);
    709     }
    710     if(children) delete children;
     777    else
     778        exceptioncode = DOMException::INDEX_SIZE_ERR;
     779    delete children;
    711780}
    712781
     
    719788  _row = -1;
    720789  cSpan = rSpan = 1;
    721   m_nowrap = false;
    722790  _id = tag;
    723791  rowHeight = 0;
     792  m_solid = false;
    724793}
    725794
     
    749818        break;
    750819    case ATTR_NOWRAP:
    751         m_nowrap = (attr->val() != 0);
     820        if (attr->val() != 0)
     821            addCSSProperty(CSS_PROP_WHITE_SPACE, "-konq-nowrap");
     822        else
     823            removeCSSProperty(CSS_PROP_WHITE_SPACE);
    752824        break;
    753825    case ATTR_WIDTH:
    754826        if (!attr->value().isEmpty())
    755             addCSSLength(CSS_PROP_WIDTH, attr->value());
     827            addCSSLength( CSS_PROP_WIDTH, attr->value() );
    756828        else
    757829            removeCSSProperty(CSS_PROP_WIDTH);
    758         break;
    759     case ATTR_HEIGHT:
    760         if (!attr->value().isEmpty())
    761             addCSSLength(CSS_PROP_HEIGHT, attr->value());
    762         else
    763             removeCSSProperty(CSS_PROP_HEIGHT);
    764830        break;
    765831    case ATTR_NOSAVE:
     
    770836}
    771837
    772 void HTMLTableCellElementImpl::init()
    773 {
    774     HTMLTablePartElementImpl::init();
    775 
     838void HTMLTableCellElementImpl::attach()
     839{
    776840    HTMLElementImpl* p = static_cast<HTMLElementImpl*>(parentNode());
    777841    while(p && p->id() != ID_TABLE)
     
    795859        }
    796860    }
     861
     862    HTMLTablePartElementImpl::attach();
    797863}
    798864
     
    800866
    801867HTMLTableColElementImpl::HTMLTableColElementImpl(DocumentPtr *doc, ushort i)
    802     : HTMLElementImpl(doc)
     868    : HTMLTablePartElementImpl(doc)
    803869{
    804870    _id = i;
     
    806872}
    807873
    808 HTMLTableColElementImpl::~HTMLTableColElementImpl()
    809 {
    810 }
    811 
    812874NodeImpl::Id HTMLTableColElementImpl::id() const
    813875{
     
    815877}
    816878
    817 
    818 NodeImpl *HTMLTableColElementImpl::addChild(NodeImpl *child)
    819 {
    820 #ifdef DEBUG_LAYOUT
    821     kdDebug( 6030 ) << nodeName().string() << "(Table)::addChild( " << child->nodeName().string() << " )" << endl;
    822 #endif
    823 
    824     switch(child->id())
    825     {
    826     case ID_COL:
    827     {
    828         // these have to come before the table definition!
    829         HTMLElementImpl::addChild(child);
    830         return child;
    831     }
    832     default:
    833         return 0;
    834         break;
    835         // ####
    836     }
    837     return child;
    838 
    839 }
    840879
    841880void HTMLTableColElementImpl::parseAttribute(AttributeImpl *attr)
     
    859898        break;
    860899    default:
    861         HTMLElementImpl::parseAttribute(attr);
     900        HTMLTablePartElementImpl::parseAttribute(attr);
    862901    }
    863902
     
    865904
    866905// -------------------------------------------------------------------------
    867 
    868 HTMLTableCaptionElementImpl::HTMLTableCaptionElementImpl(DocumentPtr *doc)
    869   : HTMLTablePartElementImpl(doc)
    870 {
    871 }
    872 
    873 HTMLTableCaptionElementImpl::~HTMLTableCaptionElementImpl()
    874 {
    875 }
    876906
    877907NodeImpl::Id HTMLTableCaptionElementImpl::id() const
  • trunk/WebCore/khtml/html/html_tableimpl.h

    r3098 r3351  
    7575    virtual Id id() const;
    7676
    77     virtual void attach();
    78    
    7977    HTMLTableCaptionElementImpl *caption() const { return tCaption; }
    8078    NodeImpl *setCaption( HTMLTableCaptionElementImpl * );
     
    9492    HTMLElementImpl *createCaption (  );
    9593    void deleteCaption (  );
    96     HTMLElementImpl *insertRow ( long index );
    97     void deleteRow ( long index );
     94    HTMLElementImpl *insertRow ( long index, int &exceptioncode );
     95    void deleteRow ( long index, int &exceptioncode );
    9896
    9997    // overrides
    10098    virtual NodeImpl *addChild(NodeImpl *child);
    10199    virtual void parseAttribute(AttributeImpl *attr);
    102 
    103     virtual void init();
    104 
    105     int cellPadding() { return m_cellPadding; }
    106    
     100    virtual void attach();
     101
    107102protected:
    108103    HTMLTableSectionElementImpl *head;
     
    111106    HTMLTableCaptionElementImpl *tCaption;
    112107
     108#if 0
    113109    Frame frame;
    114110    Rules rules;
    115 
    116     int m_cellPadding;
    117    
    118     bool incremental : 1;
    119     bool m_noBorder  : 1;
    120     bool m_solid     : 1;
     111#endif
     112
     113    bool m_noBorder     : 1;
     114    bool m_solid        : 1;
     115    uint unused         : 14;
     116    ushort padding      : 16;
    121117    friend class HTMLTableCellElementImpl;
    122118};
     
    129125public:
    130126    HTMLTablePartElementImpl(DocumentPtr *doc)
    131         : HTMLElementImpl(doc), m_solid(false)
     127        : HTMLElementImpl(doc)
    132128        { }
    133129
    134130    virtual void parseAttribute(AttributeImpl *attr);
    135 
    136 protected:
    137     bool m_solid : 1;
    138131};
    139132
     
    143136{
    144137public:
    145     HTMLTableSectionElementImpl(DocumentPtr *doc, ushort tagid);
     138    HTMLTableSectionElementImpl(DocumentPtr *doc, ushort tagid, bool implicit);
    146139
    147140    ~HTMLTableSectionElementImpl();
     
    151144    virtual NodeImpl *addChild(NodeImpl *child);
    152145   
    153     HTMLElementImpl *insertRow ( long index );
    154     void deleteRow ( long index );
    155 
    156     int numRows() const { return nrows; }
     146    HTMLElementImpl *insertRow ( long index, int& exceptioncode );
     147    void deleteRow ( long index, int& exceptioncode );
     148
     149    int numRows() const;
    157150
    158151protected:
    159152    ushort _id;
    160     int nrows;
    161153};
    162154
     
    166158{
    167159public:
    168     HTMLTableRowElementImpl(DocumentPtr *doc);
    169 
    170     ~HTMLTableRowElementImpl();
     160    HTMLTableRowElementImpl(DocumentPtr *doc)
     161        : HTMLTablePartElementImpl(doc) {}
    171162
    172163    virtual Id id() const;
     
    177168    long sectionRowIndex() const;
    178169
    179     HTMLElementImpl *insertCell ( long index );
    180     void deleteCell ( long index );
     170    HTMLElementImpl *insertCell ( long index, int &exceptioncode );
     171    void deleteCell ( long index, int &exceptioncode );
    181172
    182173protected:
     
    199190    int row() const { return _row; }
    200191    void setRow(int r) { _row = r; }
    201    
     192
    202193    int colSpan() const { return cSpan; }
    203194    int rowSpan() const { return rSpan; }
    204     bool noWrap() const { return m_nowrap; }
    205 
     195   
    206196    virtual Id id() const { return _id; }
    207197    virtual void parseAttribute(AttributeImpl *attr);
    208     virtual void init();
     198    virtual void attach();
    209199
    210200protected:
     
    215205    int _id;
    216206    int rowHeight;
    217 
    218     bool m_nowrap : 1;
    219 };
    220 
    221 // -------------------------------------------------------------------------
    222 
    223 class HTMLTableColElementImpl : public HTMLElementImpl
     207    bool m_solid        : 1;
     208};
     209
     210// -------------------------------------------------------------------------
     211
     212class HTMLTableColElementImpl : public HTMLTablePartElementImpl
    224213{
    225214public:
    226215    HTMLTableColElementImpl(DocumentPtr *doc, ushort i);
    227216
    228     ~HTMLTableColElementImpl();
    229 
    230217    virtual Id id() const;
    231218
    232219    void setTable(HTMLTableElementImpl *t) { table = t; }
    233220
    234     virtual NodeImpl *addChild(NodeImpl *child);
    235 
    236221    // overrides
    237222    virtual void parseAttribute(AttributeImpl *attr);
    238    
     223
    239224    int span() const { return _span; }
    240225
     
    253238{
    254239public:
    255     HTMLTableCaptionElementImpl(DocumentPtr *doc);
    256 
    257     ~HTMLTableCaptionElementImpl();
    258 
    259     virtual Id id() const;
    260 
     240    HTMLTableCaptionElementImpl(DocumentPtr *doc)
     241        : HTMLTablePartElementImpl(doc) {}
     242
     243    virtual Id id() const;
    261244    virtual void parseAttribute(AttributeImpl *attr);
    262245};
  • trunk/WebCore/khtml/html/htmlparser.cpp

    r3304 r3351  
    668668                    e = new HTMLTableCellElementImpl(document, ID_TD);
    669669                else if ( current->id() == ID_TABLE )
    670                     e = new HTMLTableSectionElementImpl( document, ID_TBODY );
     670                    e = new HTMLTableSectionElementImpl( document, ID_TBODY, true /* implicit */ );
    671671                else
    672672                    e = new HTMLTableRowElementImpl( document );
     
    10381038        popBlock( ID_TBODY );
    10391039        popBlock( ID_TFOOT );
    1040         n = new HTMLTableSectionElementImpl(document, t->id);
     1040        n = new HTMLTableSectionElementImpl(document, t->id, false);
    10411041        break;
    10421042
  • trunk/WebCore/khtml/rendering/bidi.cpp

    r3319 r3351  
    10331033    m_height = style()->borderTopWidth();
    10341034
    1035     if(hasPadding())
    1036     {
    1037         m_height += paddingTop();
    1038         toAdd += paddingBottom();
    1039     }
     1035    m_height += paddingTop();
     1036    toAdd += paddingBottom();
    10401037   
    10411038    if(firstChild()) {
  • trunk/WebCore/khtml/rendering/render_body.cpp

    r3098 r3351  
    2727#include "khtmlview.h"
    2828
    29 
     29#include <kglobal.h>
    3030#include <kdebug.h>
    3131
     
    103103#endif /* APPLE_CHANGES not defined */
    104104}
     105
     106int RenderBody::availableHeight() const
     107{
     108    int h = RenderFlow::availableHeight();
     109
     110    if( style()->marginTop().isFixed() )
     111        h  -= style()->marginTop().value;
     112    if( style()->marginBottom().isFixed() )
     113        h -= style()->marginBottom().value;
     114
     115    return kMax(0, h);
     116}
     117
  • trunk/WebCore/khtml/rendering/render_body.h

    r2752 r3351  
    4343    virtual void repaint(bool immediate=false);
    4444
    45 
    4645    virtual void layout();
    47 
    4846    virtual void setStyle(RenderStyle* style);
    4947
     48    virtual int availableHeight() const;
     49   
    5050protected:
    5151    virtual void paintBoxDecorations(QPainter *p,int _x, int _y,
  • trunk/WebCore/khtml/rendering/render_box.cpp

    r3280 r3351  
    108108{
    109109    short w = m_width - borderLeft() - borderRight();
    110     if (hasPadding())
    111         w -= paddingLeft() + paddingRight();
     110    w -= paddingLeft() + paddingRight();
    112111
    113112    //kdDebug( 6040 ) << "RenderBox::contentWidth(2) = " << w << endl;
     
    118117{
    119118    int h = m_height - borderTop() - borderBottom();
    120     if (hasPadding())
    121         h -= paddingTop() + paddingBottom();
     119    h -= paddingTop() + paddingBottom();
    122120
    123121    return h;
     
    716714}
    717715
    718 short RenderBox::calcReplacedWidth(bool* ieHack) const
    719 {
    720     Length w = style()->width();
    721     short width;
    722     if ( ieHack )
    723         *ieHack = style()->height().isPercent() || w.isPercent();
    724 
    725     switch( w.type ) {
    726     case Variable:
    727     {
    728         Length h = style()->height();
    729         int ih = intrinsicHeight();
    730         if ( ih > 0 && ( h.isPercent() || h.isFixed() ) )
    731             width = ( ( h.isPercent() ? calcReplacedHeight() : h.value )*intrinsicWidth() ) / ih;
    732         else
    733             width = intrinsicWidth();
    734         break;
    735     }
     716short RenderBox::calcReplacedWidth() const
     717{
     718   Length w = style()->width();
     719
     720   switch( w.type ) {
     721    case Fixed:
     722        return w.value;
    736723    case Percent:
    737724    {
    738         //RenderObject* p = parent();
    739         int cw = containingBlockWidth();
    740         if ( cw ) {
    741             width = w.minWidth( cw );
    742 #if APPLE_CHANGES
    743             // Aqua form controls have margins.  In order to make this work out well,
    744             // subtract our margins out.
     725        const int cw = containingBlockWidth();
     726        if (cw > 0) {
     727            int result = w.minWidth(cw);
     728#ifdef APPLE_CHANGES
     729            // Because we put margins on our form controls, for percentage widths, it's best to subtract
     730            // them out so the controls fit snugly and don't overflow.  This is gross.  Technically we
     731            // should probably stop using margins and build the spacing into the form controls ourselves, but
     732            // then how would the author override? -dwh
    745733            if (isFormElement())
    746                 width -= (marginLeft() + marginRight());
     734                result -= (marginLeft() + marginRight());
    747735#endif
    748         }
    749         else
    750             width = intrinsicWidth();
    751         break;
     736            return result;
     737        }
     738    }
     739    // fall through
     740    default:
     741        return intrinsicWidth();
     742    }
     743}
     744
     745int RenderBox::calcReplacedHeight() const
     746{
     747    const Length& h = style()->height();
     748    switch( h.type ) {
     749    case Percent: {
     750        int ah = availableHeight();
     751#ifdef APPLE_CHANGES
     752        // Because we put margins on our form controls, for percentage heights, it's best to subtract
     753        // them out so the controls fit snugly and don't overflow.  This is gross.  Technically we
     754        // should probably stop using margins and build the spacing into the form controls ourselves,
     755        // but then how would the author override? -dwh
     756        if (isFormElement())
     757            ah -= (marginTop() + marginBottom());
     758#endif
     759        return ah;
    752760    }
    753761    case Fixed:
    754         width = w.value;
    755         break;
     762        return h.value;
    756763    default:
    757         width = intrinsicWidth();
    758         break;
     764        return intrinsicHeight();
    759765    };
    760 
    761     return width;
    762 }
    763 
    764 int RenderBox::calcReplacedHeight() const
     766}
     767
     768int RenderBox::availableHeight() const
    765769{
    766770    Length h = style()->height();
    767     short height;
    768     switch( h.type ) {
    769     case Variable:
    770     {
    771         Length w = style()->width();
    772         int iw = intrinsicWidth();
    773         if( iw > 0 && ( w.isFixed() || w.isPercent() ))
    774             height = (( w.isPercent() ? calcReplacedWidth() : w.value ) * intrinsicHeight()) / iw;
    775         else
    776             height = intrinsicHeight();
    777     }
    778     break;
    779     case Percent:
    780     {
    781         RenderObject* p = parent();
    782         while (p && !p->isTableCell()) p = p->parent();
    783         bool doIEHack = !p;
    784         RenderObject* cb = containingBlock();
    785         if ( !cb->isTableCell() && doIEHack)
    786             height = h.minWidth( cb->root()->view()->visibleHeight() );
    787         else {
    788             if (cb->isTableCell()) {
    789                 RenderTableCell* tableCell = static_cast<RenderTableCell*>(cb);
    790                 if (tableCell->style()->height().isPercent() && tableCell->getCellPercentageHeight()) {
    791                 height = h.minWidth(tableCell->getCellPercentageHeight());
    792 #if APPLE_CHANGES
    793                 // Aqua form controls have margins.  In order to make this work out well,
    794                 // subtract our margins out.
    795                 if (isFormElement())
    796                     height -= (marginTop() + marginBottom());
    797 #endif
    798                     break;
    799                 }
    800             }
    801            
    802             if (!doIEHack)
    803                 cb = cb->containingBlock();
    804            
    805             if ( cb->style()->height().isFixed() )
    806                 height = h.minWidth( cb->style()->height().value );
    807             else
    808                 height = intrinsicHeight();
    809         }
    810     }
    811     break;
    812     case Fixed:
    813         height = h.value;
    814         break;
    815     default:
    816         height = intrinsicHeight();
    817     };
    818 
    819     return height;
     771
     772    if (h.isFixed())
     773        return h.value;
     774
     775    if (isRoot())
     776        return static_cast<const RenderRoot*>(this)->viewportHeight();
     777
     778    // We need to stop here, since we don't want to increase the height of the table
     779    // artificially.  We're going to rely on this cell getting expanded to some new
     780    // height, and then when we lay out again we'll use the calculation below.
     781    if (isTableCell() && (h.isVariable() || h.isPercent())) {
     782        const RenderTableCell* tableCell = static_cast<const RenderTableCell*>(this);
     783        return tableCell->getCellPercentageHeight() - (borderLeft()+borderRight()+paddingLeft()+paddingRight());
     784    }
     785   
     786    if (h.isPercent())
     787       return h.width(containingBlock()->availableHeight());
     788       
     789    return containingBlock()->availableHeight();
    820790}
    821791
     
    1016986        ch = hl.value + cb->paddingTop()
    1017987             + cb->paddingBottom();
     988    else if (cb->isHtml())
     989        ch = cb->availableHeight();
    1018990    else
    1019991        ch = cb->height();
     
    1023995    if(!style()->bottom().isVariable())
    1024996        b = style()->bottom().width(ch) + cb->borderBottom();
    1025     if(!style()->height().isVariable())
     997    if (isTable() && style()->height().isVariable())
     998        // Height is never unsolved for tables. "auto" means shrink to fit.  Use our
     999        // height instead.
     1000        h = m_height - pab;
     1001    else if(!style()->height().isVariable())
    10261002    {
    10271003        h = style()->height().width(ch);
  • trunk/WebCore/khtml/rendering/render_box.h

    r3098 r3351  
    102102    int calcWidthUsing(WidthType widthType, int cw, LengthType& lengthType);
    103103   
    104     virtual short calcReplacedWidth(bool* ieHack=0) const;
     104    virtual short calcReplacedWidth() const;
    105105    virtual int   calcReplacedHeight() const;
    106106
     107    virtual int availableHeight() const;
     108   
    107109    void calcVerticalMargins();
    108110
  • trunk/WebCore/khtml/rendering/render_flow.cpp

    r3304 r3351  
    417417    m_height = 0;
    418418
    419     if(style()->hasBorder())
    420     {
    421         xPos += borderLeft();
    422         m_height += borderTop();
    423         toAdd += borderBottom();
    424     }
    425     if (hasPadding())
    426     {
    427         xPos += paddingLeft();
    428         m_height += paddingTop();
    429         toAdd += paddingBottom();
    430     }
    431 
     419    xPos += borderLeft() + paddingLeft();
     420    m_height += borderTop() + paddingTop();
     421    toAdd += borderBottom() + paddingBottom();
     422   
    432423    int minHeight = m_height + toAdd;
    433424    m_overflowHeight = m_height;
     
    1004995    int left = 0;
    1005996
    1006     if (style()->hasBorder())
    1007         left += borderLeft();
    1008     if (hasPadding())
    1009         left += paddingLeft();
     997    left += borderLeft() + paddingLeft();
    1010998
    1011999    if ( firstLine && style()->direction() == LTR ) {
     
    10481036    int right = m_width;
    10491037
    1050     if (style()->hasBorder())
    1051         right -= borderRight();
    1052     if (hasPadding())
    1053         right -= paddingRight();
     1038    right -= borderRight() + paddingRight();
    10541039
    10551040    if ( firstLine && style()->direction() == RTL ) {
     
    13011286    kdDebug( 6040 ) << (void *)this << ": adding overhanging floats xoff=" << xoff << "  offset=" << offset << " child=" << child << endl;
    13021287#endif
    1303     if ( !flow->specialObjects )
     1288    if ( !flow->specialObjects || (child && flow->layer()) )
    13041289        return;
    13051290
     
    13171302            ( child && flow->yPos() + r->endY > height() ) ) ) {
    13181303           
    1319             if ( child )
     1304            if (child)
    13201305                r->noPaint = true;
    13211306               
     
    16201605void RenderFlow::calcBlockMinMaxWidth()
    16211606{
     1607    bool nowrap = style()->whiteSpace() == NOWRAP;
     1608           
    16221609    RenderObject *child = firstChild();
    16231610    while(child != 0)
     
    16711658        int w = child->minWidth() + margin;
    16721659        if(m_minWidth < w) m_minWidth = w;
     1660        // IE ignores tables for calculation of nowrap. Makes some sense.
     1661            if ( nowrap && !child->isTable() && m_maxWidth < w )
     1662            m_maxWidth = w;
     1663       
    16731664        w = child->maxWidth() + margin;
    16741665        if(m_maxWidth < w) m_maxWidth = w;
     
    16941685    }
    16951686
     1687    bool preOrNowrap = style()->whiteSpace() != NORMAL;         
    16961688    if (childrenInline())
    16971689        calcInlineMinMaxWidth();
     
    17011693    if(m_maxWidth < m_minWidth) m_maxWidth = m_minWidth;
    17021694
    1703     if (style()->width().isFixed())
     1695    if (preOrNowrap && childrenInline())
     1696        m_minWidth = m_maxWidth;
     1697       
     1698    if (style()->width().isFixed() && style()->width().value > 0)
    17041699        m_maxWidth = KMAX(m_minWidth,short(style()->width().value));
    1705 
    1706     if ( style()->whiteSpace() != NORMAL )
    1707         m_minWidth = m_maxWidth;
    1708 
     1700   
    17091701    int toAdd = 0;
    1710     if(style()->hasBorder())
    1711         toAdd = borderLeft() + borderRight();
    1712     if (hasPadding())
    1713         toAdd += paddingLeft() + paddingRight();
     1702    toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight();
    17141703
    17151704    m_minWidth += toAdd;
  • trunk/WebCore/khtml/rendering/render_form.cpp

    r3148 r3351  
    7575    return RenderWidget::baselinePosition( f ) - 2 - style()->fontMetrics().descent();
    7676#endif
    77 }
    78 
    79 short RenderFormElement::calcReplacedWidth(bool*) const
    80 {
    81     Length w = style()->width();
    82     if ( w.isVariable() )
    83         return intrinsicWidth();
    84     else
    85         return RenderReplaced::calcReplacedWidth();
    86 }
    87 
    88 int RenderFormElement::calcReplacedHeight() const
    89 {
    90     Length h = style()->height();
    91     if ( h.isVariable() )
    92         return intrinsicHeight();
    93     else
    94         return RenderReplaced::calcReplacedHeight();
    9577}
    9678
  • trunk/WebCore/khtml/rendering/render_form.h

    r3098 r3351  
    8686#endif
    8787
    88     // IE does not scale according to intrinsicWidth/Height
    89     // aspect ratio :-(
    90     virtual short calcReplacedWidth(bool* ieHack=0) const;
    91     virtual int   calcReplacedHeight() const;
    9288    virtual void updateFromElement();
    9389
  • trunk/WebCore/khtml/rendering/render_frames.cpp

    r3238 r3351  
    914914}
    915915
    916 // duplication of RenderFormElement... FIX THIS!
    917 short RenderPartObject::calcReplacedWidth(bool* ieHack) const
    918 {
    919     Length w = style()->width();
    920    
    921     // Always setting ieHack is incorrect and causes the following example test case to break.
    922     // <table width="100%" height="90">
    923     // <tr>
    924     //   <td width="200" style="border: 2px solid green">
    925     //     <object width="200" height="90" style="border: 2px solid red">
    926     //       <embed width="200" height="90" style="border: 2px solid blue"></embed>
    927     //     </object>
    928     //   </td>
    929     //   <td width="100%" style="border: 2px solid blue"></td>
    930     //   <td width="500" style="border: 2px solid green">
    931     //     <object width="500" height="90" style="border: 2px solid red">
    932     //       <embed width="500" height="90" style="border: 2px solid blue"></embed>
    933     //     </object>
    934     //   </td>
    935     // </tr>
    936     // </table>
    937     //
    938     // Real-world example is at: http://www.moveabletype.com/top.html
    939     // I am commenting this out, since it causes all plugins to have a min width of 0
    940     // all the time (unless they have a variable length).  This is clearly wrong. - dwh
    941     if ( w.isVariable() ) {
    942         if (ieHack) // Move it inside.  Only applies in the override case. -dwh
    943             *ieHack = true;
    944         return intrinsicWidth();
    945     }
    946     else
    947         return RenderReplaced::calcReplacedWidth();
    948 }
    949 
    950 int RenderPartObject::calcReplacedHeight() const
    951 {
    952     Length h = style()->height();
    953     if ( h.isVariable() )
    954         return intrinsicHeight();
    955     else
    956         return RenderReplaced::calcReplacedHeight();
    957 }
    958 // end duplication
    959 
    960916void RenderPartObject::layout( )
    961917{
  • trunk/WebCore/khtml/rendering/render_frames.h

    r2937 r3351  
    147147    virtual void updateWidget();
    148148
    149     // IE does not scale according to intrinsicWidth/Height
    150     // aspect ratio :-(
    151     virtual short calcReplacedWidth(bool* ieHack=0) const;
    152     virtual int   calcReplacedHeight() const;
    153 
    154149    virtual bool partLoadingErrorNotify( khtml::ChildFrame *childFrame, const KURL& url, const QString& serviceType );
    155150
  • trunk/WebCore/khtml/rendering/render_object.cpp

    r3160 r3351  
    109109        break;
    110110    case TABLE_CAPTION:
    111         o = new (arena) RenderTableCaption(node);
     111        o = new (arena) RenderFlow(node);
    112112        break;
    113113    }
     
    869869int RenderObject::paddingTop() const
    870870{
    871     int cw=0;
    872     if (style()->paddingTop().isPercent())
    873         cw = containingBlock()->contentWidth();
    874     return m_style->paddingTop().minWidth(cw);
     871    int w = 0;
     872    Length padding = m_style->paddingTop();
     873    if (padding.isPercent())
     874        w = containingBlock()->contentWidth();
     875    w = padding.minWidth(w);
     876    if ( isTableCell() && padding.isVariable() )
     877        w = static_cast<const RenderTableCell *>(this)->table()->cellPadding();
     878    return w;
    875879}
    876880
    877881int RenderObject::paddingBottom() const
    878882{
    879     int cw=0;
    880     if (style()->paddingBottom().isPercent())
    881         cw = containingBlock()->contentWidth();
    882     return m_style->paddingBottom().minWidth(cw);
     883    int w = 0;
     884    Length padding = style()->paddingBottom();
     885    if (padding.isPercent())
     886        w = containingBlock()->contentWidth();
     887    w = padding.minWidth(w);
     888    if ( isTableCell() && padding.isVariable() )
     889        w = static_cast<const RenderTableCell *>(this)->table()->cellPadding();
     890    return w;
    883891}
    884892
    885893int RenderObject::paddingLeft() const
    886894{
    887     int cw=0;
    888     if (style()->paddingLeft().isPercent())
    889         cw = containingBlock()->contentWidth();
    890     return m_style->paddingLeft().minWidth(cw);
     895    int w = 0;
     896    Length padding = style()->paddingLeft();
     897    if (padding.isPercent())
     898        w = containingBlock()->contentWidth();
     899    w = padding.minWidth(w);
     900    if ( isTableCell() && padding.isVariable() )
     901        w = static_cast<const RenderTableCell *>(this)->table()->cellPadding();
     902    return w;
    891903}
    892904
    893905int RenderObject::paddingRight() const
    894906{
    895     int cw=0;
    896     if (style()->paddingRight().isPercent())
    897         cw = containingBlock()->contentWidth();
    898     return m_style->paddingRight().minWidth(cw);
     907    int w = 0;
     908    Length padding = style()->paddingRight();
     909    if (padding.isPercent())
     910        w = containingBlock()->contentWidth();
     911    w = padding.minWidth(w);
     912    if ( isTableCell() && padding.isVariable() )
     913        w = static_cast<const RenderTableCell *>(this)->table()->cellPadding();
     914    return w;
    899915}
    900916
  • trunk/WebCore/khtml/rendering/render_object.h

    r3160 r3351  
    174174    virtual bool isTableRow() const { return false; }
    175175    virtual bool isTableSection() const { return false; }
     176    virtual bool isTableCol() const { return false; }
    176177    virtual bool isTable() const { return false; }
    177178    virtual bool isWidget() const { return false; }
     
    309310    virtual void close() { }
    310311
     312    virtual int availableHeight() const { return 0; }
     313   
    311314    // does a query on the rendertree and finds the innernode
    312315    // and overURL for the given position
     
    447450    virtual int paddingLeft() const;
    448451    virtual int paddingRight() const;
    449     virtual bool hasPadding() const { return style()->hasPadding(); }
    450452   
    451453    virtual int borderTop() const { return style()->borderTopWidth(); }
  • trunk/WebCore/khtml/rendering/render_replaced.cpp

    r3148 r3351  
    8383#endif
    8484
    85     bool isPercent = false;
    86     int width = calcReplacedWidth(&isPercent);
    87 
    88     int toAdd = 0;
    89     if (hasPadding())
    90         toAdd += paddingLeft() + paddingRight();
    91     if (style()->hasBorder())
    92         toAdd += borderLeft() + borderRight();
    93 
    94     if ( isPercent ) {
     85    int width = calcReplacedWidth();
     86
     87    if (!isWidget())
     88        width += paddingLeft() + paddingRight() + borderLeft() + borderRight();
     89
     90    if ( style()->width().isPercent() || style()->height().isPercent() ) {
    9591        m_minWidth = 0;
    96         m_maxWidth = width + toAdd;
     92        m_maxWidth = width;
    9793    }
    9894    else
    99         m_minWidth = m_maxWidth = width + toAdd;
     95        m_minWidth = m_maxWidth = width;
    10096
    10197    setMinMaxKnown();
  • trunk/WebCore/khtml/rendering/render_root.cpp

    r3098 r3351  
    5151    m_maxWidth = m_minWidth;
    5252
    53     m_rootWidth=0;
    54     m_rootHeight=0;
    55 
     53    m_rootWidth = m_rootHeight = 0;
     54    m_viewportWidth = m_viewportHeight = 0;
     55   
    5656    setPositioned(true); // to 0,0 :)
    5757
     
    123123void RenderRoot::layout()
    124124{
    125     //kdDebug(6040) << "RenderRoot::layout()" << endl;
    126125    if (m_printingMode)
    127126       m_minWidth = m_width;
    128127
    129     if(firstChild()) {
     128    if(firstChild())
    130129        firstChild()->setLayouted(false);
    131     }
    132130
    133131#ifdef SPEED_DEBUG
     
    139137#ifdef SPEED_DEBUG
    140138    kdDebug() << "RenderRoot::calcMinMax time used=" << qt.elapsed() << endl;
    141     // this fixes frameset resizing
    142139    qt.start();
    143140#endif
    144141
    145     RenderFlow::layout();
    146142#ifdef SPEED_DEBUG
    147143    kdDebug() << "RenderRoot::layout time used=" << qt.elapsed() << endl;
    148144    qt.start();
    149145#endif
    150     // have to do that before layoutSpecialObjects() to get fixed positioned objects at the right place
    151     if (m_view) m_view->resizeContents(docWidth(), docHeight());
    152 
    153     if (!m_printingMode && m_view)
    154     {
    155         m_height = m_view->visibleHeight();
    156         m_width = m_view->visibleWidth();
    157     }
    158     else if (!m_view)
    159     {
     146    if (!m_printingMode) {
     147        m_viewportWidth = m_width = m_view->visibleWidth();
     148        m_viewportHeight = m_height = m_view->visibleHeight();
     149    }
     150    else {
     151        m_width = m_rootWidth;
    160152        m_height = m_rootHeight;
    161         m_width = m_rootWidth;
    162     }
    163    
     153    }
     154
     155    RenderFlow::layout();
     156
     157    if (!m_printingMode) {
     158        m_view->resizeContents(docWidth(), docHeight());
     159        setWidth( m_viewportWidth = m_view->visibleWidth() );
     160        setHeight(  m_viewportHeight = m_view->visibleHeight() );
     161    }
     162
     163
    164164    // ### we could maybe do the call below better and only pass true if the docsize changed.
    165165    layoutSpecialObjects( true );
     166
    166167#ifdef SPEED_DEBUG
    167168    kdDebug() << "RenderRoot::end time used=" << qt.elapsed() << endl;
     
    170171    layer()->setHeight(m_height);
    171172    layer()->setWidth(m_width);
    172    
     173
    173174    setLayouted();
    174     //kdDebug(0) << "root: height = " << m_height << endl;
    175175}
    176176
     
    212212    }
    213213
    214 #ifdef BOX_DEBUG
    215214    if (m_view)
    216215    {
     
    218217        _ty += m_view->contentsY();
    219218    }
     219   
     220    // 3. paint floats.
     221    if (paintPhase == FLOAT_PHASE)
     222        paintFloats(p, _x, _y, _w, _h, _tx, _ty);
     223       
     224#ifdef BOX_DEBUG
    220225    outlineBox(p, _tx, _ty);
    221226#endif
  • trunk/WebCore/khtml/rendering/render_root.h

    r2752 r3351  
    7575    virtual void setHeight( int height ) { m_rootHeight = m_height = height; }
    7676
     77    int viewportWidth() const { return m_viewportWidth; }
     78    int viewportHeight() const { return m_viewportHeight; }
     79   
    7780protected:
    7881
     
    9194    int m_rootHeight;
    9295
     96    int m_viewportWidth;
     97    int m_viewportHeight;
     98   
    9399    // used to ignore viewport width when printing to the printer
    94100    bool m_printingMode;
  • trunk/WebCore/khtml/rendering/render_style.cpp

    r3098 r3351  
    3232
    3333StyleSurroundData::StyleSurroundData()
    34     : margin( Fixed ), padding( Fixed )
     34    : margin( Fixed ), padding( Variable )
    3535{
    3636}
  • trunk/WebCore/khtml/rendering/render_style.h

    r3098 r3351  
    384384
    385385enum EWhiteSpace {
    386     NORMAL, PRE, NOWRAP
     386    NORMAL, PRE, NOWRAP, KONQ_NOWRAP
    387387};
    388388
     
    642642    bool        isFloating() const { return !(noninherited_flags._floating == FNONE); }
    643643    bool        hasMargin() const { return surround->margin.nonZero(); }
    644     bool        hasPadding() const { return surround->padding.nonZero(); }
    645644    bool        hasBorder() const { return surround->border.hasBorder(); }
    646645    bool        hasOffset() const { return surround->offset.nonZero(); }
     
    706705
    707706    EClear clear() const { return  noninherited_flags._clear; }
    708     ETableLayout inheritedLayout() const { return  noninherited_flags._table_layout; }
     707    ETableLayout tableLayout() const { return  noninherited_flags._table_layout; }
    709708
    710709    short colSpan() const { return visual->colspan; }
  • trunk/WebCore/khtml/rendering/render_table.cpp

    r3286 r3351  
    77 *           (C) 1999 Lars Knoll (knoll@kde.org)
    88 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    9  * Copyright (C) 2002 Apple Computer, Inc.
    109 *
    1110 * This library is free software; you can redistribute it and/or
     
    2928//#define DEBUG_LAYOUT
    3029//#define BOX_DEBUG
    31 
    3230#include "rendering/render_table.h"
     31#include "rendering/table_layout.h"
    3332#include "html/html_tableimpl.h"
    3433#include "misc/htmltags.h"
    35 #include "xml/dom_docimpl.h"
    3634
    3735#include <kglobal.h>
     
    4543using namespace khtml;
    4644
    47 template class QMemArray<LengthType>;
    48 
    49 #define FOR_EACH_CELL(r,c,cell) \
    50     for ( unsigned int r = 0; r < totalRows; r++ )                    \
    51     {                                                                 \
    52         for ( unsigned int c = 0; c < totalCols; c++ )                \
    53         {                                                             \
    54             RenderTableCell *cell = cells[r][c];             \
    55             if (!cell)                                                \
    56                 continue;                                             \
    57             if ( (c < totalCols - 1) && (cell == cells[r][c+1]) )     \
    58                 continue;                                             \
    59             if ( (r < totalRows - 1) && (cells[r+1][c] == cell) )     \
    60                 continue;
    61 
    62 #define END_FOR_EACH } }
    63 
    64 
    6545RenderTable::RenderTable(DOM::NodeImpl* node)
    6646    : RenderFlow(node)
     
    6848
    6949    tCaption = 0;
    70     _oldColElem = 0;
    71     head = 0;
    72     foot = 0;
    73     firstBody = 0;
    74 
    75     incremental = false;
    76     m_maxWidth = 0;
    77 
     50    head = foot = firstBody = 0;
     51    tableLayout = 0;
    7852
    7953    rules = None;
    8054    frame = Void;
    81 
    82     m_cellPadding = -1;
    83    
    84     row = 0;
    85     col = 0;
    86 
    87     maxColSpan = 0;
    88 
    89     colInfos.setAutoDelete(true);
    90 
    91     _currentCol=0;
    92 
    93     _lastParentWidth = 0;
     55    has_col_elems = false;
     56    spacing = 0;
     57    padding = 0;
     58    needSectionRecalc = false;
     59    padding = 0;
    9460
    9561    columnPos.resize( 2 );
    96     colMaxWidth.resize( 1 );
    97     colMinWidth.resize( 1 );
    98     colValue.resize(1);
    99     colType.resize(1);
    100     actColWidth.resize(1);
    10162    columnPos.fill( 0 );
    102     colMaxWidth.fill( 0 );
    103     colMinWidth.fill( 0 );
    104     colValue.fill(0);
    105     colType.fill(Variable);
    106     actColWidth.fill(0);
    107 
     63    columns.resize( 1 );
     64    columns.fill( ColumnStruct() );
     65
     66    columnPos[0] = 0;
     67}
     68
     69RenderTable::~RenderTable()
     70{
     71    delete tableLayout;
     72}
     73
     74void RenderTable::setStyle(RenderStyle *_style)
     75{
     76    ETableLayout oldTableLayout = style() ? style()->tableLayout() : TAUTO;
     77    if ( _style->display() == INLINE ) _style->setDisplay(INLINE_TABLE);
     78    if ( _style->display() != INLINE_TABLE ) _style->setDisplay(TABLE);
     79    RenderFlow::setStyle(_style);
     80
     81    // init RenderObject attributes
     82    setInline(style()->display()==INLINE_TABLE && !isPositioned());
     83    setReplaced(style()->display()==INLINE_TABLE);
     84
     85    spacing = style()->borderSpacing();
    10886    columnPos[0] = spacing;
    10987
    110     totalCols = 0;   // this should be expanded to the maximum number of cols
    111                      // by the first row parsed
    112     totalRows = 0;
    113     allocRows = 5;   // allocate five rows initially
    114     rowInfo.resize( totalRows+1 );
    115     memset( rowInfo.data(), 0, (totalRows+1)*sizeof(RowInfo)); // Init to 0.
    116 
    117     cells = new RenderTableCell ** [allocRows];
    118 
    119     for ( unsigned int r = 0; r < allocRows; r++ )
    120     {
    121         cells[r] = new RenderTableCell * [totalCols];
    122         memset( cells[r], 0, totalCols * sizeof( RenderTableCell * ));
    123     }
    124     needsCellsRecalc = false;
    125     colWidthKnown = false;
    126     hasPercent = false;
    127 }
    128 
    129 RenderTable::~RenderTable()
    130 {
    131     for ( unsigned int r = 0; r < allocRows; r++ )
    132         delete [] cells[r];
    133     delete [] cells;
     88    if ( !tableLayout || style()->tableLayout() != oldTableLayout ) {
     89        delete tableLayout;
     90
     91        if (style()->tableLayout() == TFIXED ) {
     92            tableLayout = new FixedTableLayout(this);
     93#ifdef DEBUG_LAYOUT
     94            kdDebug( 6040 ) << "using fixed table layout" << endl;
     95#endif
     96        } else
     97            tableLayout = new AutoTableLayout(this);
     98    }
     99}
     100
     101void RenderTable::position(int x, int y, int, int, int, bool, bool, int)
     102{
     103    //for inline tables only
     104    m_x = x + marginLeft();
     105    m_y = y + marginTop();
    134106}
    135107
     
    152124}
    153125
    154 void RenderTable::setStyle(RenderStyle *_style)
    155 {
    156     RenderFlow::setStyle(_style);
    157 
    158     // init RenderObject attributes
    159     // In quirks mode, we will accept display: inline and block as valid
    160     // display types for a table object (see www.sundancecatalog.com).
    161     // A table therefore should go ahead and check if it's inline as well
    162     // as inline-table.
    163     bool isTableInline = style()->display() == INLINE_TABLE ||
    164                          style()->display() == INLINE;
    165     setInline(isTableInline && !isPositioned());
    166     setReplaced(isTableInline);
    167    
    168     spacing = style()->borderSpacing();
    169     collapseBorders = style()->borderCollapse();
    170 }
    171 
    172 void RenderTable::position(int x, int y, int, int, int, bool, bool, int)
    173 {
    174     //for inline tables only
    175     m_x = x + marginLeft();
    176     m_y = y + marginTop();
    177 }
    178 
    179126void RenderTable::addChild(RenderObject *child, RenderObject *beforeChild)
    180127{
     
    183130                       (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;
    184131#endif
     132    RenderObject *o = child;
     133
    185134    if (child->element() && child->element()->id() == ID_FORM) {
    186135        RenderContainer::addChild(child,beforeChild);
    187136        return;
    188137    }
    189            
    190     RenderObject *o = child;
    191    
     138
    192139    switch(child->style()->display())
    193140    {
    194141    case TABLE_CAPTION:
    195         tCaption = static_cast<RenderTableCaption *>(child);
     142        tCaption = static_cast<RenderFlow *>(child);
    196143        break;
    197144    case TABLE_COLUMN:
    198145    case TABLE_COLUMN_GROUP:
    199         {
    200             RenderContainer::addChild(child,beforeChild);
    201             RenderTableCol* colel = static_cast<RenderTableCol *>(child);
    202             if (_oldColElem && _oldColElem->style()->display() == TABLE_COLUMN_GROUP)
    203                 _currentCol = _oldColElem->lastCol();
    204             _oldColElem = colel;
    205             colel->setStartCol(_currentCol);
    206             if ( colel->span() != 0 ) {
    207                 if (child->style()->display() == TABLE_COLUMN)
    208                     _currentCol++;
    209                 else
    210                     _currentCol+=colel->span();
    211                 addColInfo(colel);
    212             }
    213             incremental = true;
    214             colel->setTable(this);
    215         }
    216         child->setLayouted( false );
    217         child->setMinMaxKnown( false );
     146        RenderContainer::addChild(child,beforeChild);
     147        has_col_elems = true;
    218148        return;
    219149    case TABLE_HEADER_GROUP:
    220         if(incremental && !columnPos[totalCols]);// calcColWidth();
    221 //      setTHead(static_cast<RenderTableSection *>(child));
     150        if ( !head )
     151            head = static_cast<RenderTableSection *>(child);
     152        else if ( !firstBody )
     153            firstBody = static_cast<RenderTableSection *>(child);
    222154        break;
    223155    case TABLE_FOOTER_GROUP:
    224         if(incremental && !columnPos[totalCols]);// calcColWidth();
    225 //      setTFoot(static_cast<RenderTableSection *>(child));
    226         break;
     156        if ( !foot ) {
     157            foot = static_cast<RenderTableSection *>(child);
     158            break;
     159        }
     160        // fall through
    227161    case TABLE_ROW_GROUP:
    228         if(incremental && !columnPos[totalCols]);// calcColWidth();
    229162        if(!firstBody)
    230163            firstBody = static_cast<RenderTableSection *>(child);
    231164        break;
    232165    default:
    233         if ( !beforeChild )
    234             beforeChild = lastChild();
    235         if ( beforeChild && beforeChild->isAnonymousBox() )
    236             o = beforeChild;
    237         else {
     166        if ( !beforeChild && lastChild() &&
     167             lastChild()->isTableSection() && lastChild()->isAnonymousBox() ) {
     168            o = lastChild();
     169        } else {
    238170            RenderObject *lastBox = beforeChild;
    239171            while ( lastBox && lastBox->parent()->isAnonymousBox() &&
     
    244176                return;
    245177            } else {
    246 //          kdDebug( 6040 ) << "creating anonymous table section" << endl;
     178                if ( beforeChild && !beforeChild->isTableSection() )
     179                    beforeChild = 0;
     180                //kdDebug( 6040 ) << this <<" creating anonymous table section beforeChild="<< beforeChild << endl;
    247181                o = new (renderArena()) RenderTableSection(0 /* anonymous */);
    248182                RenderStyle *newStyle = new RenderStyle();
    249183                newStyle->inheritFrom(style());
    250                 newStyle->setDisplay(TABLE_ROW_GROUP);
     184                newStyle->setDisplay(TABLE_ROW_GROUP);
    251185                o->setStyle(newStyle);
    252186                o->setIsAnonymousBox(true);
     
    260194    }
    261195    RenderContainer::addChild(child,beforeChild);
    262     child->setTable(this);
    263 }
    264 
    265 void RenderTable::startRow()
    266 {
    267     while ( col < totalCols && cells[row][col] != 0 )
    268         col++;
    269     if ( col )
    270         row++;
    271     col = 0;
    272     if(row > totalRows) totalRows = row;
    273     if (totalRows == 0)
    274         totalRows = 1; // Go ahead and acknowledge that we have one row. -dwh.
    275 }
    276 
    277 void RenderTable::closeRow()
    278 {
    279     while ( col < totalCols && cells[row][col] != 0L )
    280         col++;
    281 
    282     if (col<=0) return;
    283 
    284     RenderTableCell* cell = cells[row][col-1];
    285 
    286     if (!cell) return;
    287 }
    288 
    289 void RenderTable::addCell( RenderTableCell *cell )
    290 {
    291     while ( col < totalCols && cells[row][col] != 0L )
    292         col++;
    293     setCells( row, col, cell );
    294 
    295     col++;
    296 }
    297 
    298 
    299 void RenderTable::setCells( unsigned int r, unsigned int c,
    300                                      RenderTableCell *cell )
    301 {
    302 #ifdef TABLE_DEBUG
    303     kdDebug( 6040 ) << "setCells: span = " << cell->rowSpan() << "/" << cell->colSpan() << " pos = " << r << "/" << c << endl;
    304 #endif
    305     cell->setRow(r);
    306     cell->setCol(c);
    307 
    308     unsigned int endRow = r + cell->rowSpan();
    309     unsigned int endCol = c + cell->colSpan();
    310 
    311     if ( endCol > totalCols )
    312         addColumns( endCol - totalCols );
    313 
    314     if ( endRow >= allocRows )
    315         addRows( endRow - allocRows + 10 );
    316 
    317     if ( endRow > totalRows )
    318         totalRows = endRow;
    319 
    320     for ( ; r < endRow; r++ ) {
    321         for ( unsigned int tc = c; tc < endCol; tc++ ) {
    322             cells[r][tc] = cell;
    323         }
    324     }
    325 }
    326 
    327 void RenderTable::addRows( int num )
    328 {
    329     RenderTableCell ***newRows =
    330         new RenderTableCell ** [allocRows + num];
    331     memcpy( newRows, cells, allocRows * sizeof(RenderTableCell **) );
    332     delete [] cells;
    333     cells = newRows;
    334 
    335     for ( unsigned int r = allocRows; r < allocRows + num; r++ )
    336     {
    337         cells[r] = new RenderTableCell * [totalCols];
    338         memset( cells[r], 0, totalCols * sizeof( RenderTableCell * ));
    339     }
    340 
    341     allocRows += num;
    342 }
    343 
    344 void RenderTable::addColumns( int num )
    345 {
    346 #ifdef TABLE_DEBUG
    347     kdDebug( 6040 ) << "addColumns() totalCols=" << totalCols << " new=" << num << endl;
    348 #endif
    349     RenderTableCell **newCells;
    350 
    351     int newCols = totalCols + num;
    352     // resize the col structs to the number of columns
    353     columnPos.resize(newCols+1);
    354     memset( columnPos.data() + totalCols + 1, 0, num*sizeof(int));
    355     colMaxWidth.resize(newCols);
    356     memset( colMaxWidth.data() + totalCols , 0, num*sizeof(int));
    357     colMinWidth.resize(newCols);
    358     memset( colMinWidth.data() + totalCols , 0, num*sizeof(int));
    359     colValue.resize(newCols);
    360     memset( colValue.data() + totalCols , 0, num*sizeof(int));
    361     colType.resize(newCols);
    362     memset( colType.data() + totalCols , 0, num*sizeof(LengthType));
    363     actColWidth.resize(newCols);
    364     memset( actColWidth.data() + totalCols , 0, num*sizeof(LengthType));
    365 
    366     for ( unsigned int r = 0; r < allocRows; r++ )
    367     {
    368         newCells = new RenderTableCell * [newCols];
    369         memcpy( newCells, cells[r],
    370                 totalCols * sizeof( RenderTableCell * ) );
    371         memset( newCells + totalCols, 0,
    372                 num * sizeof( RenderTableCell * ) );
    373         delete [] cells[r];
    374         cells[r] = newCells;
    375     }
    376 
    377     int mSpan = newCols;
    378 
    379     colInfos.resize(mSpan);
    380 
    381     for ( unsigned int c =0 ; c < totalCols; c++ )
    382     {
    383         colInfos[c]->resize(newCols);
    384     }
    385     for ( unsigned int c = totalCols; (int)c < newCols; c++ )
    386     {
    387         colInfos.insert(c, new ColInfoLine(newCols-c+1));
    388     }
    389 
    390     totalCols = newCols;
    391 }
    392 
    393 
    394 void RenderTable::recalcColInfos()
    395 {
    396 //    kdDebug(0) << "RenderTable::recalcColInfos()" << endl;
    397     for (int s=0 ; s<maxColSpan; s++)
    398     {
    399         for (unsigned int c=0 ; c<totalCols; c++)
    400             if (c<colInfos[s]->size())
    401                 colInfos[s]->remove(c);
    402     }
    403 
    404     maxColSpan = 0;
    405 
    406     FOR_EACH_CELL(r,c,cell)
    407         addColInfo(cell);
    408     END_FOR_EACH
    409 }
    410 
    411 void RenderTable::recalcColInfo( ColInfo *col )
    412 {
    413     //qDebug("------------- recalcColinfo: line=%d, span=%d", col->start, col->span-1);
    414 
    415     KHTMLAssert( colInfos[col->span-1]->at(col->start) == col );
    416 
    417     // We need to recalc all the members of the column. -dwh
    418     bool needRecalc = true;
    419 
    420     // add table-column if exists
     196}
     197
     198
     199
     200void RenderTable::calcWidth()
     201{
     202    if ( isPositioned() ) {
     203        calcAbsoluteHorizontal();
     204    }
     205
     206    RenderObject *cb = containingBlock();
     207    int availableWidth = cb->contentWidth();
     208
     209    LengthType widthType = style()->width().type;
     210    if(widthType > Relative && style()->width().value > 0) {
     211        // Percent or fixed table
     212        m_width = style()->width().minWidth( availableWidth );
     213        if(m_minWidth > m_width) m_width = m_minWidth;
     214        //kdDebug( 6040 ) << "1 width=" << m_width << " minWidth=" << m_minWidth << " availableWidth=" << availableWidth << " " << endl;
     215    } else {
     216        m_width = KMIN(short( availableWidth ),m_maxWidth);
     217    }
     218
     219    // restrict width to what we really have in case we flow around floats
     220    if ( style()->flowAroundFloats() && cb->isFlow() ) {
     221        availableWidth = static_cast<RenderFlow *>(cb)->lineWidth( m_y );
     222        m_width = QMIN( availableWidth, m_width );
     223    }
     224
     225    m_width = KMAX (m_width, m_minWidth);
     226
     227    m_marginRight=0;
     228    m_marginLeft=0;
     229
     230    calcHorizontalMargins(style()->marginLeft(),style()->marginRight(),availableWidth);
     231}
     232
     233void RenderTable::layout()
     234{
     235    KHTMLAssert( !layouted() );
     236    KHTMLAssert( minMaxKnown() );
     237    KHTMLAssert( !needSectionRecalc );
     238
     239    //kdDebug( 6040 ) << renderName() << "(Table)"<< this << " ::layout0() width=" << width() << ", layouted=" << layouted() << endl;
     240
     241    m_height = 0;
     242
     243    //int oldWidth = m_width;
     244    calcWidth();
     245
     246    // the optimisation below doesn't work since the internal table
     247    // layout could have changed.  we need to add a flag to the table
     248    // layout that tells us if something has changed in the min max
     249    // calculations to do it correctly.
     250//     if ( oldWidth != m_width || columns.size() + 1 != columnPos.size() )
     251    tableLayout->layout();
     252
     253#ifdef DEBUG_LAYOUT
     254    kdDebug( 6040 ) << renderName() << "(Table)::layout1() width=" << width() << ", marginLeft=" << marginLeft() << " marginRight=" << marginRight() << endl;
     255#endif
     256
     257    setCellWidths();
     258
     259    // layout child objects
     260    int calculatedHeight = 0;
     261
    421262    RenderObject *child = firstChild();
    422263    while( child ) {
    423         if ( child->style()->display() == TABLE_COLUMN ||
    424              child->style()->display() == TABLE_COLUMN_GROUP ) {
    425             RenderTableCol *tc = static_cast<RenderTableCol *>(child);
    426             if ( tc->span() == col->span && tc->col() == col->start ) {
    427                 if (needRecalc) {
    428                     needRecalc = false;
    429                     col->needsRecalc();
    430                 }
    431                 addColInfo( tc );
    432                 break;
    433             }
    434         } else {
    435             break;
     264        if ( !child->layouted() )
     265            child->layout();
     266        if ( child->isTableSection() ) {
     267            static_cast<RenderTableSection *>(child)->calcRowHeight();
     268            calculatedHeight += static_cast<RenderTableSection *>(child)->layoutRows( 0 );
    436269        }
    437270        child = child->nextSibling();
    438271    }
    439272
    440     // now the cells
    441     for ( unsigned int r = 0; r < totalRows; r++ ) {
    442         RenderTableCell *cell = cells[r][col->start];
    443         if ( cell && cell->colSpan() == col->span ) {
    444             if (needRecalc) {
    445                 needRecalc = false;
    446                 col->needsRecalc();
    447             }
    448             addColInfo(cell, false);
    449         }
    450     }
    451    
    452     if (needRecalc)
    453         // Null out and delete the column.
    454         colInfos[col->span-1]->remove(col->start);
    455 
    456     setMinMaxKnown( false );
    457 
    458     //qDebug("------------- end recalcColinfo");
    459 }
    460 
    461 
    462 void RenderTable::addColInfo(RenderTableCol *colel)
    463 {
    464 
    465     int _startCol = colel->col();
    466     int span = colel->span();
    467     int _minSize=0;
    468     int _maxSize=0;
    469     Length _width = colel->style()->width();
    470     if (_width.type==Fixed) {
    471         _maxSize=_width.value;
    472         _minSize=_width.value;
    473     }
    474 
    475     for (int n=0; n<span; ++n) {
    476 #ifdef TABLE_DEBUG
    477         kdDebug( 6040 ) << "COL Element" << endl;
    478         kdDebug( 6040 ) << "    startCol=" << _startCol << " span=" << span << endl;
    479         kdDebug( 6040 ) << "    min=" << _minSize << " max=" << _maxSize << " val=" << _width.value << endl;
    480 #endif
    481         addColInfo(_startCol+n, 1 , _minSize, _maxSize, _width ,0);
    482     }
    483 
    484 }
    485 
    486 void RenderTable::addColInfo(RenderTableCell *cell, bool allowRecalc)
    487 {
    488 
    489     int _startCol = cell->col();
    490     int _colSpan = cell->colSpan();
    491     int _minSize = cell->minWidth();
    492     int _maxSize = cell->maxWidth();
    493 
    494 #if 0
    495     // We do need to implement "collapse borders", but just doing this
    496     // fudge on the calculation of the column widths is not enough to do so.
    497     // This alone simply makes borders draw incorrectly.
    498     if (collapseBorders)
    499     {
    500         int bw = cell->borderLeft() + cell->borderRight();
    501         _minSize -= bw;
    502         _maxSize -= bw;
    503     }
    504 #endif
    505 
    506     Length _width = cell->style()->width();
    507     addColInfo(_startCol, _colSpan, _minSize, _maxSize, _width ,cell, allowRecalc);
    508 }
    509 
    510 void RenderTable::addColInfo(int _startCol, int _colSpan,
    511                                       int _minSize, int _maxSize,
    512                                       Length _width, RenderTableCell* _cell, bool allowRecalc )
    513 {
    514     // Netscape ignores width values of "0" or "0%"
    515     if ( style()->htmlHacks() && _width.value == 0 && (_width.type == Percent || _width.type == Fixed) )
    516             _width = Length();
    517 
    518     if (_startCol + _colSpan > (int) totalCols)
    519         addColumns(totalCols - _startCol + _colSpan);
    520 
    521     ColInfo* col = colInfos[_colSpan-1]->at(_startCol);
    522 
    523     bool changed = false;
    524     bool recalc = false;
    525 
    526     if (!col) {
    527         col = new ColInfo;
    528         colInfos[_colSpan-1]->insert(_startCol,col);
    529     }
    530    
    531     if (col->needRecalc) {
    532         col->needRecalc = false;
    533         col->span = _colSpan;
    534         col->start = _startCol;
    535         col->minCell = _cell;
    536         col->maxCell = _cell;
    537         col->min = _minSize;
    538         col->max = _maxSize;
    539         if (_colSpan>maxColSpan)
    540             maxColSpan=_colSpan;
    541         col->type = _width.type;
    542         col->value = _width.value;
    543         col->widthCell = _cell;
    544 
    545         changed = true;
    546     } else {
    547         if (_minSize != col->min) {
    548             if ( allowRecalc && col->minCell == _cell ) {
    549                 recalc = true;
    550             } else if ( _minSize > col->min ) {
    551                 col->min = _minSize;
    552                 col->minCell = _cell;
    553                 changed = true;
    554             }
    555         }
    556         if (_maxSize != col->max) {
    557             if ( allowRecalc && col->maxCell == _cell ) {
    558                 recalc = true;
    559             } else if (_maxSize > col->max) {
    560                 col->max = _maxSize;
    561                 col->maxCell = _cell;
    562                 changed = true;
    563             }
    564         }
    565 
    566         // Fixed width is treated as variable
    567 
    568         if (_width.type == col->type && _width.value > col->value ) {
    569             if ( allowRecalc && col->widthCell == _cell ) {
    570                 recalc = true;
    571             } else {
    572                 col->value = _width.value;
    573                 col->widthCell = _cell;
    574                 changed = true;
    575             }
    576         } else if ( (_width.type > int(col->type) && (!(_width.type==Fixed) || (int(col->type)<=Variable)))
    577                     || ( col->type == Fixed && !(_width.type==Variable)) ) {
    578             if ( allowRecalc && col->widthCell == _cell ) {
    579                 recalc = true;
    580             } else {
    581                 col->type = _width.type;
    582                 col->value = _width.value;
    583                 col->widthCell = _cell;
    584                 changed = true;
    585             }
    586         }
    587     }
    588    
    589     if ( recalc )
    590         recalcColInfo( col );
    591 
    592     if ( changed )
    593         setMinMaxKnown(false);
    594 
    595     if ( recalc || changed )
    596         colWidthKnown = false;
    597 
    598 #ifdef TABLE_DEBUG
    599     kdDebug( 6040 ) << "(" << this << "):addColInfo():" << endl;
    600     kdDebug( 6040 ) << "    startCol=" << col->start << " span=" << col->span << endl;
    601     kdDebug( 6040 ) << "    min=" << col->min << " max=" << col->max << endl;
    602     kdDebug( 6040 ) << "    type=" << col->type << " width=" << col->value << endl;
    603 #endif
    604 
    605 }
    606 
    607 void RenderTable::spreadSpanMinMax(int col, int span, int distmin,
    608     int distmax, LengthType type)
    609 {
    610 #ifdef TABLE_DEBUG
    611     kdDebug( 6040 ) << "RenderTable::spreadSpanMinMax() " << type << " " << distmin << " " << distmax << endl;
    612 #endif
    613 
    614     if (distmin<1)
    615         distmin=0;
    616     if (distmax<1)
    617         distmax=0;
    618     if (distmin<1 && distmax<1)
    619         return;
    620 
    621 
    622     bool hasUsableCols=false;
    623     int tmax=distmax;
    624     int tmin=distmin;
    625     int c;
    626 
    627     for (c=col; c < col+span ; ++c)
    628     {
    629 
    630         if (colType[c]<=type || (type == Variable && distmax==0))
    631         {
    632             hasUsableCols=true;
    633             break;
    634         }
    635     }
    636 
    637     if (hasUsableCols) {
    638         // spread span maxWidth
    639         for (int i = LengthType(Variable); i <= int(Fixed) && i <= type && tmax; ++i)
    640             tmax = distributeMaxWidth(tmax,type,LengthType(i),col,span);
    641 
    642 
    643         // spread span minWidth
    644         for (int i = LengthType(Variable); i <= int(Fixed) && i <= type && tmin; ++i)
    645             tmin = distributeMinWidth(tmin,type,LengthType(i),col,span,true);
    646 
    647         // force spread rest of the minWidth
    648         for (int i = LengthType(Variable); i <= int(Fixed) && tmin; ++i)
    649             tmin = distributeMinWidth(tmin,type,LengthType(i),col,span,false);
    650 
    651         for (int c=col; c < col+span ; ++c)
    652             colMaxWidth[c]=KMAX(colMinWidth[c],colMaxWidth[c]);
    653     }
    654 }
    655 
    656 
    657 int RenderTable::distributeMinWidth(int distrib, LengthType distType,
    658             LengthType toType, int start, int span, bool mlim )
    659 {
    660 //    kdDebug( 6040 ) << "MINDIST, " << distrib << " pixels of type " << distType << " to type " << toType << " cols sp=" << span << " " << endl;
    661 
    662     int olddis=0;
    663     int c=start;
    664     int totper=0;
    665 
    666     int tdis = distrib;
    667 
    668     if (!mlim)
    669     {
    670         // first target unused columns
    671         for(; c<start+span; ++c)
    672         {
    673             if (colInfos[0]->at(c)==0)
    674             {
    675                 colMinWidth[c]+=tdis;
    676                 colType[c]=distType;
    677                 tdis=0;
    678                 break;
    679             }
    680         }
    681     }
    682 
    683     if (toType==Percent || toType==Relative)
    684         for (int n=start;n<start+span;n++)
    685             if (colType[n]==Percent || colType[n]==Relative) totper += colValue[n];
    686 
    687     c=start;
    688     while(tdis>0)
    689     {
    690 //      kdDebug( 6040 ) << c << ": ct=" << colType[c] << " min=" << colMinWidth[c]
    691 //                << " max=" << colMaxWidth[c] << endl;
    692         if (colType[c]==toType || (mlim && colMaxWidth[c]-colMinWidth[c]>0))
    693         {
    694             int delta = distrib/span;
    695             if (totper)
    696                 delta=(distrib * colValue[c])/totper;
    697             if (mlim)
    698                 delta = KMIN(delta,colMaxWidth[c]-colMinWidth[c]);
    699 
    700             delta = KMIN(tdis,delta);
    701 
    702             if (delta==0 && tdis && (!mlim || colMaxWidth[c]>colMinWidth[c]))
    703                 delta=1;
    704 
    705 //            kdDebug( 6040 ) << "delta=" << delta << endl;
    706 
    707             colMinWidth[c]+=delta;
    708             if (mlim)
    709                 colType[c]=distType;
    710             tdis-=delta;
    711         }
    712         if (++c==start+span)
    713         {
    714             c=start;
    715             if (olddis==tdis)
    716                 break;
    717             olddis=tdis;
    718         }
    719     }
    720 
    721     return tdis;
    722 }
    723 
    724 
    725 
    726 int RenderTable::distributeMaxWidth(int distrib, LengthType/* distType*/,
    727             LengthType toType, int start, int span)
    728 {
    729 //    kdDebug( 6040 ) << "MAXDIST, " << distrib << " pixels of type " << distType << " to type " << toType << " cols sp=" << span << " " << endl;
    730     int olddis=0;
    731     int c=start;
    732 
    733     int tdis = distrib;
    734 
    735     // spread span maxWidth evenly
    736     c=start;
    737     while(tdis>0)
    738     {
    739 //      kdDebug( 6040 ) << c << ": ct=" << colType[c] << " min=" << colMinWidth[c]
    740 //                << " max=" << colMaxWidth[c] << endl;
    741 
    742         if (colType[c]==toType)
    743         {
    744             colMaxWidth[c]+=distrib/span;
    745             tdis-=distrib/span;
    746             if (tdis<span)
    747             {
    748                 colMaxWidth[c]+=tdis;
    749                 tdis=0;
    750             }
    751         }
    752         if (++c==start+span)
    753         {
    754             c=start;
    755             if (olddis==tdis)
    756                 break;
    757             olddis=tdis;
    758         }
    759     }
    760     return tdis;
    761 }
    762 
    763 
    764 
    765 void RenderTable::calcSingleColMinMax(int c, ColInfo* col)
    766 {
    767 #ifdef TABLE_DEBUG
    768     kdDebug( 6040 ) << "RenderTable::calcSingleColMinMax()" << endl;
    769 #endif
    770 
    771     int span=col->span;
    772     int smin = col->min;
    773     int smax = col->max;
    774 
    775     if (span==1)
    776     {
    777       //kdDebug( 6040 ) << "col (s=1) c=" << c << ",m=" << smin << ",x=" << smax << endl;
    778         colMinWidth[c] = smin;
    779         colMaxWidth[c] = smax;
    780         colValue[c] = col->value;
    781         colType[c] = col->type;
    782     }
    783     else
    784     {
    785         int oldmin=0;
    786         int oldmax=0;
    787         for (int o=c; o<c+span; ++o)
    788         {
    789             oldmin+=colMinWidth[o];
    790             oldmax+=colMaxWidth[o];
    791         }
    792         int spreadmin = smin-oldmin-(span-1)*spacing;
    793 //        kdDebug( 6040 ) << "colmin " << smin  << endl;
    794 //        kdDebug( 6040 ) << "oldmin " << oldmin  << endl;
    795 //        kdDebug( 6040 ) << "oldmax " << oldmax  << endl;
    796 //      kdDebug( 6040 ) << "spreading span " << spreadmin  << endl;
    797         spreadSpanMinMax
    798             (c, span, spreadmin, 0 , col->type);
    799     }
    800 
    801 }
    802 
    803 void RenderTable::calcFinalColMax(int c, ColInfo* col)
    804 {
    805 #ifdef TABLE_DEBUG
    806     kdDebug( 6040 ) << "RenderTable::calcPercentRelativeMax()" << endl;
    807 #endif
    808     int span=col->span;
    809 
    810     int oldmax=0;
    811     int oldmin=0;
    812 
    813     for (int o=c; o<c+span; ++o)
    814     {
    815         oldmax+=colMaxWidth[o];
    816         oldmin+=colMinWidth[o];
    817     }
    818 
    819     int smax = col->max;
    820 
    821     if (col->type == Percent)
    822     {
    823         smax = m_width * col->value / KMAX(100u,totalPercent);
    824     }
    825     else if (col->type == Relative && totalRelative)
    826     {
    827         smax = m_width * col->value / totalRelative;
    828     }
    829 
    830     smax = KMAX(smax,oldmin);
    831 
    832 //    kdDebug( 6040 ) << "smin " << smin << " smax " << smax << " span " << span << endl;
    833     if (span==1)
    834     {
    835 //       kdDebug( 6040 ) << "col (s=1) c=" << c << ",m=" << smin << ",x=" << smax << endl;
    836        colMaxWidth[c] = smax;
    837        colType[c] = col->type;
    838     }
    839     else
    840     {
    841         int spreadmax = smax-oldmax-(span-1)*spacing;
    842 //      kdDebug( 6040 ) << "spreading span " << spreadmax << endl;
    843         spreadSpanMinMax
    844             (c, span, 0, spreadmax, col->type);
    845     }
    846 
    847 }
    848 
    849 
    850 
    851 void RenderTable::calcColMinMax()
    852 {
    853 // Calculate minmimum and maximum widths for all
    854 // columns.
    855 // Calculate min and max width for the table.
    856 
    857     // PHASE 1, prepare
    858 
    859     colMinWidth.fill(0);
    860     colMaxWidth.fill(0);
    861 
    862     int availableWidth = containingBlockWidth();
    863 
    864     int realMaxWidth=spacing;
    865 
    866     int* spanPercent = new int[maxColSpan];
    867     int* spanPercentMax = new int[maxColSpan];
    868 
    869     LengthType widthType = style()->width().type;
    870 
    871 #ifdef TABLE_DEBUG
    872     kdDebug( 6040 ) << "RenderTable(" << this << ")::calcColMinMax(), maxCelSpan" << maxColSpan << " totalCols " << totalCols << " widthtype=" << widthType << " widthval=" << style()->width().value << endl;
    873 #endif
    874 
    875     Length l;
    876     if ( ( l = style()->marginLeft() ).isFixed() )
    877         availableWidth -= QMAX( l.value, 0 );
    878     if ( ( l = style()->marginRight() ).isFixed() )
    879         availableWidth -= QMAX( l.value, 0 );
    880 
    881     availableWidth -= QMAX( style()->borderLeftWidth(), 0 );
    882     availableWidth -= QMAX( style()->borderRightWidth(), 0 );
    883     // PHASE 2, calculate simple minimums and maximums
    884     for ( unsigned int s=0;  (int)s<maxColSpan ; ++s)
    885     {
    886         ColInfoLine* spanCols = colInfos[s];
    887 
    888         int spanMax=0;
    889         spanPercentMax[s] = spacing;
    890         spanPercent[s] = 0;
    891 
    892         for ( unsigned int c=0; c<totalCols-s; ++c)
    893         {
    894             ColInfo* col;
    895             col = spanCols->at(c);
    896 
    897             if (!col || col->span==0)
    898                 continue;
    899 #ifdef TABLE_DEBUG
    900             kdDebug( 6040 ) << " s=" << s << " c=" << c << " min=" << col->min << " value=" << col->value  <<
    901                         " max="<<col->max<< endl;
    902 #endif
    903 
    904             spanMax += col->max + spacing;
    905 
    906             if (col->type==Percent)
    907             {
    908                 spanPercentMax[s] += col->max+spacing;
    909                 spanPercent[s] += col->value;
    910             }
    911 
    912             calcSingleColMinMax(c, col);
    913 
    914             if ( col->span>1 && widthType != Percent
    915                 && (col->type==Variable || col->type==Fixed))
    916             {
    917                 calcFinalColMax(c, col);
    918             }
    919 
    920         }
    921 
    922         // this should be some sort of generic path algorithm
    923         // but we'll just hack it for now
    924         if (spanMax>realMaxWidth)
    925             realMaxWidth=spanMax;
    926     }
    927 
    928     // PHASE 3, calculate table width
    929 
    930     totalPercent=0;
    931     totalRelative=0;
    932 
    933     int minPercent=0;
    934     int maxPercent=0;
    935 
    936     int minRel=0;
    937     int minVar=0;
    938     int maxRel=0;
    939     int maxVar=0;
    940     hasPercent=false;
    941     bool hasRel=false;
    942     bool hasVar=false;
    943 
    944     int maxPercentColumn=0;
    945     int maxTentativePercentWidth=0;
    946 
    947     m_minWidth = spacing;
    948     m_maxWidth = spacing;
    949 
    950     for(int i = 0; i < (int)totalCols; i++)
    951     {
    952         m_minWidth += colMinWidth[i] + spacing;
    953         m_maxWidth += colMaxWidth[i] + spacing;
    954 
    955         switch(colType[i])
    956         {
    957         case Percent:
    958             if (!hasPercent){
    959                 hasPercent=true;
    960                 minPercent=maxPercent=spacing;
    961             }
    962             totalPercent += colValue[i];
    963 
    964             maxPercentColumn = KMAX(colValue[i],maxPercentColumn);
    965 
    966             minPercent += colMinWidth[i] + spacing;
    967             maxPercent += colMaxWidth[i] + spacing;
    968 
    969             maxTentativePercentWidth = KMAX(colValue[i]==0?0:colMaxWidth[i]*100/colValue[i],
    970                     maxTentativePercentWidth);
    971             break;
    972         case Relative:
    973             if (!hasRel){
    974                 hasRel=true;
    975                 minRel=maxRel=spacing;
    976             }
    977             totalRelative += colValue[i] ;
    978             minRel += colMinWidth[i] + spacing;
    979             maxRel += colMaxWidth[i] + spacing;
    980             break;
    981         case Variable:
    982         case Fixed:
    983         default:
    984             if (!hasVar){
    985                 hasVar=true;
    986                 minVar=maxVar=spacing;
    987             }
    988             minVar += colMinWidth[i] + spacing;
    989             maxVar += colMaxWidth[i] + spacing;
    990         }
    991 
    992     }
    993 
    994     for ( int s=0; s<maxColSpan ; ++s)
    995     {
    996         maxPercent = KMAX(spanPercentMax[s],maxPercent);
    997         totalPercent = KMAX(spanPercent[s],int(totalPercent));
    998     }
    999     delete[] spanPercentMax;
    1000     delete[] spanPercent;
    1001 
    1002     if (widthType <= Relative && hasPercent) {
    1003         int tot = KMIN(100u, totalPercent );
    1004 
    1005         if (tot>0)
    1006             m_maxWidth = maxPercent*100/tot;
    1007 
    1008         if (tot<100)
    1009             m_maxWidth = KMAX( short((maxVar+maxRel)*100/(100-tot)), m_maxWidth );
    1010         else if (hasRel || hasVar || ((int)totalPercent>maxPercentColumn && maxPercentColumn>=100))
    1011             m_maxWidth = 10000;
    1012         else if (totalPercent>0)
    1013             m_maxWidth = KMAX(short(maxTentativePercentWidth*100/totalPercent), m_maxWidth);
    1014 
    1015     }
    1016 
    1017 
    1018 
    1019     // PHASE 5, set table min and max to final values
    1020 
    1021     if(widthType == Fixed) {
    1022         m_width = style()->width().value;
    1023         if ( m_width < m_minWidth )
    1024             m_width = m_minWidth;
    1025         m_minWidth = m_maxWidth = m_width;
    1026     } else {
    1027         if (realMaxWidth > m_maxWidth)
    1028             m_maxWidth = realMaxWidth;
    1029     }
    1030 
    1031     m_minWidth += borderLeft() + borderRight();
    1032     m_maxWidth += borderLeft() + borderRight();
    1033 
    1034 #ifdef TABLE_DEBUG
    1035     kdDebug( 6040 ) << "TABLE width=" << m_width <<
    1036                 " m_minWidth=" << m_minWidth <<
    1037                 " m_maxWidth=" << m_maxWidth <<
    1038                 " realMaxWidth=" << realMaxWidth << endl;
    1039 #endif
    1040 }
    1041 
    1042 void RenderTable::calcWidth()
    1043 {
    1044     if ( isPositioned() ) {
    1045         calcAbsoluteHorizontal();
    1046     }
    1047 
    1048     RenderObject *cb = containingBlock();
    1049     int availableWidth = cb->contentWidth();
    1050 
    1051     LengthType widthType = style()->width().type;
    1052     if(widthType > Relative) {
    1053         // Percent or fixed table
    1054         m_width = style()->width().minWidth( availableWidth );
    1055         if(m_minWidth > m_width) m_width = m_minWidth;
    1056         //kdDebug( 6040 ) << "1 width=" << m_width << " minWidth=" << m_minWidth << " availableWidth=" << availableWidth << " " << endl;
    1057     } else if (hasPercent) {
    1058         m_width = KMIN(short( availableWidth ),m_maxWidth);
    1059 //        kdDebug( 6040 ) << "width=" << m_width << " maxPercent=" << maxPercent << " maxVar=" << maxVar << " " << endl;
    1060     } else {
    1061         m_width = KMIN(short( availableWidth ),m_maxWidth);
    1062     }
    1063 
    1064     // restrict width to what we really have in case we flow around floats
    1065     if ( style()->flowAroundFloats() && cb->isFlow() )
    1066         m_width = QMIN( static_cast<RenderFlow *>(cb)->lineWidth( m_y ), m_width );
    1067 
    1068     m_width = KMAX (m_width, m_minWidth);
    1069 
    1070     m_marginRight=0;
    1071     m_marginLeft=0;
    1072 
    1073     calcHorizontalMargins(style()->marginLeft(),style()->marginRight(),availableWidth);
    1074 
    1075     // PHASE 4, calculate maximums for percent and relative columns. We can't do this in
    1076     // the minMax calculations, as we do not have the correct table width there.
    1077 
    1078     for ( unsigned int s=0;  (int)s<maxColSpan ; ++s) {
    1079         ColInfoLine* spanCols = colInfos[s];
    1080         for ( unsigned int c=0; c<totalCols-s; ++c) {
    1081             ColInfo* col;
    1082             col = spanCols->at(c);
    1083 
    1084             if (!col || col->span==0)
    1085                 continue;
    1086             if (col->type==Variable || col->type==Fixed)
    1087                 continue;
    1088 
    1089             calcFinalColMax(c, col);
    1090         }
    1091     }
    1092 }
    1093 
    1094 void RenderTable::calcColWidth(void)
    1095 {
    1096 
    1097 #ifdef TABLE_DEBUG
    1098     kdDebug( 6040 ) << "START calcColWidth() this = " << this << endl;
    1099     kdDebug( 6040 ) << "maxColSpan = " << maxColSpan << endl;
    1100 #endif
    1101 
    1102     colWidthKnown = true;
    1103 
    1104     if (totalCols==0)
    1105         return;
    1106 
    1107     /*
    1108      * Set actColWidth[] to column minimums, it will
    1109      * grow from there.
    1110      * Collect same statistics for future use.
    1111      */
    1112 
    1113     int actWidth = spacing + borderLeft() + borderRight();
    1114 
    1115     int minFixed = 0;
    1116     int minPercent = 0;
    1117     int minRel = 0;
    1118     int minVar = 0;
    1119 
    1120     int maxFixed = 0;
    1121     int maxPercent = 0;
    1122     int maxRel = 0;
    1123     int maxVar = 0;
    1124 
    1125     int numFixed = 0;
    1126     int numPercent = 0;
    1127     int numRel = 0;
    1128     int numVar = 0;
    1129 
    1130     actColWidth.fill(0);
    1131 
    1132     unsigned int i;
    1133     for(i = 0; i < totalCols; i++)
    1134     {
    1135         actColWidth[i] = colMinWidth[i];
    1136         actWidth += actColWidth[i] + spacing;
    1137 
    1138         switch(colType[i])
    1139         {
    1140         case Fixed:
    1141             minFixed += colMinWidth[i];
    1142             maxFixed += colMaxWidth[i];
    1143             numFixed++;
    1144             break;
    1145         case Percent:
    1146             minPercent += colMinWidth[i];
    1147             maxPercent += colMaxWidth[i];
    1148             numPercent++;
    1149             break;
    1150         case Relative:
    1151             minRel += colMinWidth[i];
    1152             maxRel += colMaxWidth[i];
    1153             numRel++;
    1154             break;
    1155         case Variable:
    1156         default:
    1157             minVar += colMinWidth[i];
    1158             maxVar += colMaxWidth[i];
    1159             numVar++;
    1160         }
    1161 
    1162     }
    1163 
    1164 #ifdef TABLE_DEBUG
    1165     for(int i = 0; i < (int)totalCols; i++)
    1166     {
    1167         kdDebug( 6040 ) << "Start->target " << i << ": " << actColWidth[i] << "->" << colMaxWidth[i] << " type=" << colType[i] << endl;
    1168     }
    1169 #endif
    1170 
    1171     int toAdd = m_width - actWidth;      // what we can add
    1172 
    1173 #ifdef TABLE_DEBUG
    1174     kdDebug( 6040 ) << "toAdd = width - actwidth: " << toAdd << " = " << m_width << " - " << actWidth << endl;
    1175 #endif
    1176 
    1177     /*
    1178      * distribute the free width among the columns so that
    1179      * they reach their max width.
    1180      * Order: percent->fixed->relative->variable
    1181      */
    1182 
    1183     toAdd = distributeWidth(toAdd,Percent,numPercent);
    1184     toAdd = distributeWidth(toAdd,Fixed,numFixed);
    1185     toAdd = distributeWidth(toAdd,Relative,numRel);
    1186     toAdd = distributeWidth(toAdd,Variable,numVar);
    1187 
    1188 #ifdef TABLE_DEBUG
    1189     for(int i = 0; i < (int)totalCols; i++)
    1190     {
    1191         kdDebug( 6040 ) << "distributeWidth->target " << i << ": " << actColWidth[i] << "->" << colMaxWidth[i] << " type=" << colType[i] << endl;
    1192     }
    1193 #endif
    1194 
    1195     /*
    1196      * Some width still left?
    1197      * Reverse order, variable->relative->percent
    1198      */
    1199 
    1200     if ( numVar ) toAdd = distributeRest(toAdd,Variable,maxVar);
    1201     if ( numRel ) toAdd = distributeRest(toAdd,Relative,maxRel);
    1202     if ( numPercent ) toAdd = distributeRest(toAdd,Percent,maxPercent);
    1203     if ( numFixed ) toAdd = distributeRest(toAdd,Fixed,maxFixed);
    1204 
    1205 #ifdef TABLE_DEBUG
    1206     for(int i = 0; i < (int)totalCols; i++)
    1207     {
    1208         kdDebug( 6040 ) << "distributeRest->target " << i << ": " << actColWidth[i] << "->" << colMaxWidth[i] << " type=" << colType[i] << endl;
    1209     }
    1210 #endif
    1211     /*
    1212      * If something remains, put it to the last column
    1213      */
    1214     actColWidth[totalCols-1] += toAdd;
    1215 
    1216     /*
    1217      * Calculate the placement of colums
    1218      */
    1219 
    1220     columnPos.fill(0);
    1221     columnPos[0] = spacing;
    1222     for(i = 1; i <= totalCols; i++)
    1223     {
    1224         columnPos[i] += columnPos[i-1] + actColWidth[i-1] + spacing;
    1225 #ifdef TABLE_DEBUG
    1226         kdDebug( 6040 ) << "Actual width col " << i << ": " << actColWidth[i-1] << " pos = " << columnPos[i-1] << endl;
    1227 #endif
    1228     }
    1229 
    1230 #ifdef TABLE_DEBUG
    1231     if(m_width - borderLeft() - borderLeft() != columnPos[totalCols] )
    1232         kdDebug( 6040 ) << "========> table layout error!!! <===============================" << endl;
    1233     kdDebug( 6040 ) << "total width = " << m_width << " colpos = " << columnPos[totalCols] << endl;
    1234 #endif
    1235 
    1236 }
    1237 
    1238 
    1239 int RenderTable::distributeWidth(int distrib, LengthType type, int typeCols )
    1240 {
    1241     int olddis=0;
    1242     int c=0;
    1243 
    1244     int tdis = distrib;
    1245 #ifdef TABLE_DEBUG
    1246     kdDebug( 6040 ) << "DISTRIBUTING " << distrib << " pixels to type " << type << " cols" << endl;
    1247 #endif
    1248 
    1249     while(tdis>0)
    1250     {
    1251         if (colType[c]==type)
    1252         {
    1253             int delta = KMIN(distrib/typeCols,colMaxWidth[c]-actColWidth[c]);
    1254             delta = KMIN(tdis,delta);
    1255             if (delta==0 && tdis && colMaxWidth[c]>actColWidth[c])
    1256                 delta=1;
    1257             actColWidth[c]+=delta;
    1258             tdis-=delta;
    1259         }
    1260         if (++c == (int)totalCols)
    1261         {
    1262             c=0;
    1263             if (olddis==tdis)
    1264                 break;
    1265             olddis=tdis;
    1266         }
    1267     }
    1268     return tdis;
    1269 }
    1270 
    1271 
    1272 int RenderTable::distributeRest(int distrib, LengthType type, int divider )
    1273 {
    1274     if ( !divider )
    1275         return distrib;
    1276 
    1277 #ifdef TABLE_DEBUG
    1278     kdDebug( 6040 ) << "DISTRIBUTING rest, " << distrib << " pixels to type " << type << " cols" << endl;
    1279 #endif
    1280 
    1281     int olddis=0;
    1282     int c=0;
    1283 
    1284     int tdis = distrib;
    1285 
    1286     while(tdis>0)
    1287     {
    1288         if (colType[c]==type)
    1289         {
    1290             int delta = colMaxWidth[c] * distrib / divider;
    1291             delta=KMIN(delta,tdis);
    1292             actColWidth[c] += delta;
    1293             tdis -= delta;
    1294         }
    1295         if (++c == (int)totalCols)
    1296         {
    1297             c=0;
    1298             if (olddis==tdis)
    1299                 break;
    1300             olddis=tdis;
    1301         }
    1302     }
    1303     return tdis;
    1304 }
    1305 
    1306 
    1307 void RenderTable::calcRowHeight(int r)
    1308 {
    1309     unsigned int c;
    1310     int indx;//, borderExtra = border ? 1 : 0;
    1311     RenderTableCell *cell;
    1312 
    1313     rowInfo.resize( totalRows+1 );
    1314     rowInfo[0].height =  spacing + borderTop();
    1315     rowInfo[0].percentage = 0;
    1316    
    1317   //int oldheight = rowHeights[r+1] - rowHeights[r];
    1318     rowInfo[r+1].height = rowInfo[r+1].percentage = 0;
    1319 
    1320     int baseline=0;
    1321     int bdesc=0;
    1322     int ch;
    1323 
    1324     for ( c = 0; c < totalCols; c++ )
    1325     {
    1326         if ( ( cell = cells[r][c] ) == 0 )
    1327             continue;
    1328         if ( c < totalCols - 1 && cell == cells[r][c+1] )
    1329             continue;
    1330         if ( r < (int)totalRows - 1 && cells[r+1][c] == cell )
    1331             continue;
    1332 
    1333         if ( ( indx = r - cell->rowSpan() + 1 ) < 0 )
    1334             indx = 0;
    1335 
    1336         Length height = cell->style()->height();
    1337         ch = height.width(0);
    1338         if ( cell->height() > ch)
    1339             ch = cell->height();
    1340 
    1341         if (height.isPercent() && height.value > rowInfo[r+1].percentage)
    1342             rowInfo[r+1].percentage = height.value;
    1343            
    1344         int rowPos = rowInfo[ indx ].height + ch +
    1345              spacing ; // + padding
    1346 
    1347         if ( rowPos > rowInfo[r+1].height )
    1348             rowInfo[r+1].height = rowPos;
    1349 
    1350         // find out the baseline
    1351         EVerticalAlign va = cell->style()->verticalAlign();
    1352         if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP
    1353             || va == SUPER || va == SUB)
    1354         {
    1355             int b=cell->baselinePosition();
    1356 
    1357             if (b>baseline)
    1358                 baseline=b;
    1359 
    1360             int td = rowInfo[ indx ].height + ch - b;
    1361             if (td>bdesc)
    1362                 bdesc = td;
    1363         }
    1364     }
    1365 
    1366     //do we have baseline aligned elements?
    1367     if (baseline)
    1368     {
    1369         // increase rowheight if baseline requires
    1370         int bRowPos = baseline + bdesc  + spacing ; // + 2*padding
    1371         if (rowInfo[r+1].height<bRowPos)
    1372             rowInfo[r+1].height=bRowPos;
    1373 
    1374         rowInfo[r].baseline=baseline;
    1375     }
    1376 
    1377     if ( rowInfo[r+1].height < rowInfo[r].height )
    1378         rowInfo[r+1].height = rowInfo[r].height;
    1379 }
    1380 
    1381 void RenderTable::layout()
    1382 {
    1383     KHTMLAssert( !layouted() );
    1384     KHTMLAssert( minMaxKnown() );
    1385 
    1386     //kdDebug( 6040 ) << renderName() << "(Table)"<< this << " ::layout0() width=" << width() << ", layouted=" << layouted() << endl;
    1387 
    1388     _lastParentWidth = containingBlockWidth();
    1389 
    1390     m_height = 0;
    1391 
    1392     int oldWidth = m_width;
    1393     calcWidth();
    1394     if ( !colWidthKnown || oldWidth != m_width )
    1395         calcColWidth();
    1396 
    1397 #ifdef DEBUG_LAYOUT
    1398     kdDebug( 6040 ) << renderName() << "(Table)::layout1() width=" << width() << ", marginLeft=" << marginLeft() << " marginRight=" << marginRight() << endl;
    1399 #endif
    1400 
    1401 
    1402     setCellWidths();
    1403 
    1404     // ### collapse caption margin, left, right
    1405     if(tCaption && tCaption->style()->captionSide() != CAPBOTTOM)
    1406     {
    1407         tCaption->setPos(m_height, tCaption->marginLeft());
    1408         if ( !tCaption->layouted() )
    1409             tCaption->layout();
     273    // ### collapse caption margin
     274    if(tCaption && tCaption->style()->captionSide() != CAPBOTTOM) {
     275        tCaption->setPos(tCaption->marginLeft(), m_height);
    1410276        m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom();
    1411277    }
    1412278
    1413     // layout child objects
    1414     RenderObject *child = firstChild();
    1415     while( child ) {
    1416         if ( child != tCaption && !child->layouted() && !(child->element() && child->element()->id() == ID_FORM))
    1417             child->layout();
    1418         child = child->nextSibling();
    1419     }
    1420 
    1421     // layout rows
    1422     layoutRows(m_height);
    1423 
    1424     m_height += rowInfo[totalRows].height;
    1425     m_height += borderBottom();
    1426 
    1427     if(tCaption && tCaption->style()->captionSide()==CAPBOTTOM)
    1428     {
    1429         tCaption->setPos(tCaption->marginLeft(), m_height);
    1430         if ( !tCaption->layouted() )
    1431             tCaption->layout();
    1432         m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom();
    1433     }
    1434 
    1435     //kdDebug(0) << "table height: " << m_height << endl;
    1436 
    1437     calcHeight();
    1438 
    1439     //kdDebug(0) << "table height: " << m_height << endl;
    1440 
    1441     // table can be containing block of positioned elements.
    1442     // ### only pass true if width or height changed.
    1443     layoutSpecialObjects( true );
    1444 
    1445     setLayouted();
    1446 
    1447 }
    1448 
    1449 
    1450 void RenderTable::layoutRows(int yoff)
    1451 {
    1452     int rHeight;
    1453     int indx, rindx;
    1454 
    1455     for ( unsigned int r = 0; r < totalRows; r++ ) {
    1456         calcRowHeight(r);
    1457     }
     279    m_height += borderTop();
    1458280
    1459281    // html tables with percent height are relative to view
     
    1488310        }
    1489311    }
    1490    
    1491     bool tableGrew = false;
    1492     if (th && totalRows)
    1493     {
    1494         th-=(totalRows+1)*spacing;
    1495         int dh = th-rowInfo[totalRows].height;
    1496         if (dh>0)
    1497         {
    1498             // There is room to grow.  Distribute the space among the rows
    1499             // by weighting according to their calculated heights,
    1500             // unless there are rows that have percentage
    1501             // heights.  In that case, only the rows with percentage heights
    1502             // get the space, and the weight is distributed after computing
    1503             // a normalized flex. -dwh
    1504             tableGrew = true;
    1505             int totalPercentage = 0;
    1506             for ( unsigned int r = 0; r < totalRows; r++ )
    1507                 totalPercentage += rowInfo[r+1].percentage;
    1508                        
    1509             int tot=rowInfo[totalRows].height;
    1510             int add=0;
    1511             int prev=rowInfo[0].height;
    1512             for ( unsigned int r = 0; r < totalRows; r++ )
    1513             {
    1514                 //weight with the original height
    1515                 if (totalPercentage) {
    1516                     if (rowInfo[r+1].percentage)
    1517                         add += (rowInfo[r+1].percentage/totalPercentage)*dh;
    1518                 }
    1519                 else if (tot)
    1520                     add+=dh*(rowInfo[r+1].height-prev)/tot;
    1521                 prev=rowInfo[r+1].height;
    1522                 rowInfo[r+1].height+=add;
    1523             }
    1524            
    1525             int remaining = th - (rowInfo[totalRows].height + add);
    1526             if (remaining > 0 && totalRows > 0)
    1527                 // Just give the space to the last row.
    1528                 rowInfo[totalRows-1].height += remaining;
    1529            
    1530             rowInfo[totalRows].height=th;
     312
     313    // layout rows
     314    if ( th > calculatedHeight ) {
     315        // we have to redistribute that height to get the constraint correctly
     316        // just force the first body to the height needed
     317        // ### FIXME This should take height constraints on all table sections into account and distribute
     318        // accordingly. For now this should be good enough
     319        if (firstBody) {
     320            firstBody->calcRowHeight();
     321            firstBody->layoutRows( th - calculatedHeight );
    1531322        }
    1532323    }
    1533 
    1534 
    1535     for ( unsigned int r = 0; r < totalRows; r++ )
    1536     {
    1537         for ( unsigned int c = 0; c < totalCols; c++ )
    1538         {
    1539             RenderTableCell *cell = cells[r][c];
    1540             if (!cell)
    1541                 continue;
    1542             if ( c < totalCols - 1 && cell == cells[r][c+1] )
    1543                 continue;
    1544             if ( r < totalRows - 1 && cell == cells[r+1][c] )
    1545                 continue;
    1546 
    1547             if ( ( indx = c-cell->colSpan()+1 ) < 0 )
    1548                 indx = 0;
    1549 
    1550             if ( ( rindx = r-cell->rowSpan()+1 ) < 0 )
    1551                 rindx = 0;
    1552 
    1553             //kdDebug( 6040 ) << "setting position " << r << "/" << indx << "-" << c << ": " << //columnPos[indx] + padding << "/" << rowHeights[rindx] << " " << endl;
    1554             rHeight = rowInfo[r+1].height - rowInfo[rindx].height -
    1555                 spacing;
    1556 
    1557             cell->setRowHeight(rHeight);
    1558             bool cellChildrenFlex = false;
    1559             if (rowInfo[r+1].percentage) {
    1560                 // Force the child to lay itself out again.
    1561                 // This will cause, e.g., textareas to grow to
    1562                 // fill the area.  XXX <div>s and blocks still don't
    1563                 // work right. -dwh
    1564                 cell->setCellPercentageHeight(rHeight);
    1565                 RenderObject* o = cell->firstChild();
    1566                 while (o) {
    1567                     if (o->style()->height().isPercent())
    1568                         o->setLayouted(false);
    1569                     o = o->nextSibling();
    1570                 }
    1571                 if (!cell->layouted()) {
    1572                     cellChildrenFlex = true;
    1573                     cell->layout();
    1574                 }
    1575             }
    1576    
    1577             if (cellChildrenFlex) {
    1578                 // Alignment within a cell is based off the calculated
    1579                 // height, which becomes irrelevant once the cell has
    1580                 // been resized based off its percentage. -dwh
    1581                 cell->setCellTopExtra(0);
    1582                 cell->setCellBottomExtra(0);
    1583             }
    1584             else {
    1585                 EVerticalAlign va = cell->style()->verticalAlign();
    1586                 int te=0;
    1587                 switch (va)
    1588                 {
    1589                 case SUB:
    1590                 case SUPER:
    1591                 case TEXT_TOP:
    1592                 case TEXT_BOTTOM:
    1593                 case BASELINE:
    1594                     te = getBaseline(r) - cell->baselinePosition() ;
    1595                     break;
    1596                 case TOP:
    1597                     te = 0;
    1598                     break;
    1599                 case MIDDLE:
    1600                     te = (rHeight - cell->height())/2;
    1601                     break;
    1602                 case BOTTOM:
    1603                     te = rHeight - cell->height();
    1604                     break;
    1605                 default:
    1606                     break;
    1607                 }
    1608     #ifdef DEBUG_LAYOUT
    1609                 kdDebug( 6040 ) << "CELL te=" << te << ", be=" << rHeight - cell->height() - te << ", rHeight=" << rHeight << ", valign=" << va << endl;
    1610     #endif
    1611                 cell->setCellTopExtra( te );
    1612                 cell->setCellBottomExtra( rHeight - cell->height() - te);
    1613             }
    1614            
    1615             if (style()->direction()==RTL)
    1616             {
    1617                 cell->setPos( columnPos[(int)totalCols]
    1618                     - columnPos[(int)(indx+cell->colSpan())] + borderLeft(),
    1619                     rowInfo[rindx].height+yoff );
    1620             }
    1621             else
    1622                 cell->setPos( columnPos[indx] + borderLeft(), rowInfo[rindx].height+yoff );
    1623 
    1624             // ###
    1625             // cell->setHeight(cellHeight);
    1626         }
    1627     }
    1628 }
    1629 
     324    int bl = borderLeft();
     325
     326    // position the table sections
     327    if ( head ) {
     328        head->setPos(bl, m_height);
     329        m_height += head->height();
     330    }
     331    RenderObject *body = firstBody;
     332    while ( body ) {
     333        if ( body != head && body != foot && body->isTableSection() ) {
     334            body->setPos(bl, m_height);
     335            m_height += body->height();
     336        }
     337        body = body->nextSibling();
     338    }
     339    if ( foot ) {
     340        foot->setPos(bl, m_height);
     341        m_height += foot->height();
     342    }
     343
     344
     345    m_height += borderBottom();
     346
     347    if(tCaption && tCaption->style()->captionSide()==CAPBOTTOM) {
     348        tCaption->setPos(tCaption->marginLeft(), m_height);
     349        m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom();
     350    }
     351
     352    //kdDebug(0) << "table height: " << m_height << endl;
     353
     354    calcHeight();
     355
     356    //kdDebug(0) << "table height: " << m_height << endl;
     357
     358    // table can be containing block of positioned elements.
     359    // ### only pass true if width or height changed.
     360    layoutSpecialObjects( true );
     361
     362    setLayouted();
     363
     364}
    1630365
    1631366void RenderTable::setCellWidths()
     
    1635370#endif
    1636371
    1637 
    1638     int indx;
    1639     FOR_EACH_CELL( r, c, cell)
    1640         {
    1641             if ( ( indx = c-cell->colSpan()+1) < 0 )
    1642                 indx = 0;
    1643             int w = columnPos[c+1] - columnPos[ indx ] - spacing; //- padding*2;
    1644 
    1645 #ifdef TABLE_DEBUG
    1646             kdDebug( 6040 ) << "0x" << this << ": setting width " << r << "/" << indx << "-" << c << " (0x" << cell << "): " << w << " " << endl;
    1647 #endif
    1648             int oldWidth = cell->width();
    1649             cell->setWidth( w );
    1650             if ( w != oldWidth )
    1651                 cell->setLayouted(false);
    1652         }
    1653     END_FOR_EACH
    1654 
    1655 }
    1656 
    1657 void RenderTable::paint(QPainter *p, int _x, int _y,
    1658                         int _w, int _h, int _tx, int _ty, int paintPhase)
    1659 {
    1660 
    1661 //     if(!layouted()) return;
    1662 
     372    RenderObject *child = firstChild();
     373    while( child ) {
     374        if ( child->isTableSection() )
     375            static_cast<RenderTableSection *>(child)->setCellWidths();
     376        child = child->nextSibling();
     377    }
     378}
     379
     380void RenderTable::paint( QPainter *p, int _x, int _y,
     381                                  int _w, int _h, int _tx, int _ty, int paintPhase)
     382{
     383    if (!layouted())
     384        return;
     385       
    1663386    _tx += xPos();
    1664387    _ty += yPos();
     
    1674397
    1675398#ifdef TABLE_PRINT
    1676      kdDebug( 6040 ) << "RenderTable::paint(2) " << _tx << "/" << _ty << " (" << _x << "/" << _y << ")" << endl;
    1677 #endif
    1678     // the case below happens during parsing
    1679     // when we have a new table that never got layouted. Don't paint it.
    1680     if ( totalRows == 1 && rowInfo[1].height == 0 )
    1681         return;
    1682 
    1683     if (paintPhase == BACKGROUND_PHASE && style()->visibility() == VISIBLE)
    1684          paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
    1685 
    1686     int topextra = 0;
    1687 
    1688     if ( tCaption ) {
    1689         tCaption->paint( p, _x, _y, _w, _h, _tx, _ty, paintPhase );
    1690         if (tCaption->style()->captionSide() != CAPBOTTOM)
    1691             topextra = - borderTopExtra();
    1692     }
    1693 
    1694     // check which rows and cols are visible and only paint these
    1695     // ### fixme: could use a binary search here
    1696     unsigned int startrow = 0;
    1697     unsigned int endrow = totalRows;
    1698     for ( ; startrow < totalRows; startrow++ ) {
    1699         if ( _ty + topextra + rowInfo[startrow+1].height > _y )
    1700             break;
    1701     }
    1702     for ( ; endrow > 0; endrow-- ) {
    1703         if ( _ty + topextra + rowInfo[endrow-1].height < _y + _h )
    1704             break;
    1705     }
    1706     unsigned int startcol = 0;
    1707     unsigned int endcol = totalCols;
    1708     if ( style()->direction() == LTR ) {
    1709     for ( ; startcol < totalCols; startcol++ ) {
    1710         if ( _tx + columnPos[startcol+1] > _x )
    1711             break;
    1712     }
    1713     for ( ; endcol > 0; endcol-- ) {
    1714         if ( _tx + columnPos[endcol-1] < _x + _w )
    1715             break;
    1716     }
    1717     }
    1718 
    1719     // draw the cells
    1720     for ( unsigned int r = startrow; r < endrow; r++ ) {
    1721         for ( unsigned int c = startcol; c < endcol; c++ ) {
    1722             RenderTableCell *cell = cells[r][c];
    1723             if (!cell)
    1724                 continue;
    1725             if ( (c < endcol - 1) && (cell == cells[r][c+1]) )
    1726                 continue;
    1727             if ( (r < endrow - 1) && (cells[r+1][c] == cell) )
    1728                 continue;
    1729 #ifdef DEBUG_LAYOUT
    1730             kdDebug( 6040 ) << "painting cell " << r << "/" << c << endl;
    1731 #endif
    1732             cell->paint( p, _x, _y, _w, _h, _tx, _ty, paintPhase);
    1733         }
     399    kdDebug( 6040 ) << "RenderTable::paint(2) " << _tx << "/" << _ty << " (" << _y << "/" << _h << ")" << endl;
     400#endif
     401
     402    if(paintPhase == BACKGROUND_PHASE && style()->visibility() == VISIBLE)
     403        paintBoxDecorations(p, _x, _y, _w, _h, _tx, _ty);
     404
     405    RenderObject *child = firstChild();
     406    while( child ) {
     407        if ( child->isTableSection() || child == tCaption )
     408            child->paint( p, _x, _y, _w, _h, _tx, _ty, paintPhase );
     409        child = child->nextSibling();
    1734410    }
    1735411
     
    1743419    KHTMLAssert( !minMaxKnown() );
    1744420
    1745     if ( needsCellsRecalc )
    1746        recalcCells();
     421    if ( needSectionRecalc )
     422        recalcSections();
     423
    1747424#ifdef DEBUG_LAYOUT
    1748425    kdDebug( 6040 ) << renderName() << "(Table " << this << ")::calcMinMaxWidth()" <<  endl;
    1749426#endif
    1750427
    1751     /*
    1752      * Calculate min and max width for every column,
    1753      * Max width for percent cols are still not accurate, but as they don't
    1754      * influence the total max width of the table we don't care.
    1755      */
    1756      calcColMinMax();
     428    tableLayout->calcMinMaxWidth();
     429
     430    if (tCaption && tCaption->minWidth() > m_minWidth)
     431        m_minWidth = tCaption->minWidth();
    1757432
    1758433    setMinMaxKnown();
    1759434#ifdef DEBUG_LAYOUT
    1760     kdDebug( 6040 ) << renderName() << "END: (Table " << this << ")::calcMinMaxWidth() min = " << m_minWidth << " max = " << m_maxWidth <<  endl;
     435    kdDebug( 6040 ) << renderName() << " END: (Table " << this << ")::calcMinMaxWidth() min = " << m_minWidth << " max = " << m_maxWidth <<  endl;
    1761436#endif
    1762437}
     
    1786461}
    1787462
    1788 void RenderTable::setNeedsCellsRecalc()
    1789 {
    1790     needsCellsRecalc = true;
    1791     setMinMaxKnown(false);
    1792     setLayouted(false);
    1793 }
    1794 
    1795 void RenderTable::recalcCells()
    1796 {
    1797     needsCellsRecalc = false;
    1798 
    1799     _oldColElem = 0;
    1800     m_maxWidth = 0;
    1801 
    1802     row = 0;
    1803     col = 0;
    1804 
    1805     maxColSpan = 0;
    1806 
    1807     _currentCol=0;
    1808 
    1809     _lastParentWidth = 0;
    1810 
    1811     columnPos.resize( 0 );
    1812     columnPos.resize( 1 );
    1813     colMaxWidth.resize( 0 );
    1814     colMaxWidth.resize( 1 );
    1815     colMinWidth.resize( 0 );
    1816     colMinWidth.resize( 1 );
    1817     colValue.resize(0);
    1818     colValue.resize(1);
    1819     colType.resize(0);
    1820     colType.resize(1);
    1821     actColWidth.resize(0);
    1822     actColWidth.resize(1);
    1823     columnPos.fill( 0 );
    1824     colMaxWidth.fill( 0 );
    1825     colMinWidth.fill( 0 );
    1826     colValue.fill(0);
    1827     colType.fill(Variable);
    1828     actColWidth.fill(0);
    1829 
    1830     columnPos[0] = spacing;
    1831 
    1832     for (unsigned int r = 0; r < allocRows; r++)
    1833     {
    1834         delete[] cells[r];
    1835     }
    1836     delete[] cells;
    1837 
    1838     totalCols = 0;   // this should be expanded to the maximum number of cols
    1839                      // by the first row parsed
    1840     totalRows = 0;
    1841     allocRows = 5;   // allocate five rows initially
    1842 
    1843     cells = new RenderTableCell ** [allocRows];
    1844 
    1845     for ( unsigned int r = 0; r < allocRows; r++ )
    1846     {
    1847         cells[r] = new RenderTableCell * [totalCols];
    1848         memset( cells[r], 0, totalCols * sizeof( RenderTableCell * ));
    1849     }
    1850 
    1851     for (RenderObject *s = m_first; s; s = s->nextSibling()) {
    1852         if (s->isTableSection()) {
    1853             for (RenderObject *r = static_cast<RenderTableSection*>(s)->firstChild(); r; r = r->nextSibling()) {
    1854                 if (r->isTableRow()) {
    1855                     startRow();
    1856                     for (RenderObject *c = static_cast<RenderTableRow*>(r)->firstChild(); c; c = c->nextSibling()) {
    1857                         if (c->isTableCell())
    1858                             addCell(static_cast<RenderTableCell*>(c));
    1859                     }
    1860                     closeRow();
    1861                 }
     463
     464void RenderTable::splitColumn( int pos, int firstSpan )
     465{
     466    // we need to add a new columnStruct
     467    int oldSize = columns.size();
     468    columns.resize( oldSize + 1 );
     469    int oldSpan = columns[pos].span;
     470//     qDebug("splitColumn( %d,%d ), oldSize=%d, oldSpan=%d", pos, firstSpan, oldSize, oldSpan );
     471    KHTMLAssert( oldSpan > firstSpan );
     472    columns[pos].span = firstSpan;
     473    memmove( columns.data()+pos+1, columns.data()+pos, (oldSize-pos)*sizeof(ColumnStruct) );
     474    columns[pos+1].span = oldSpan - firstSpan;
     475
     476    // change width of all rows.
     477    RenderObject *child = firstChild();
     478    while ( child ) {
     479        if ( child->isTableSection() ) {
     480            RenderTableSection *section = static_cast<RenderTableSection *>(child);
     481            int size = section->grid.size();
     482            int row = 0;
     483            if ( section->cCol > pos )
     484                section->cCol++;
     485            while ( row < size ) {
     486                section->grid[row].row->resize( oldSize+1 );
     487                RenderTableSection::Row &r = *section->grid[row].row;
     488                memmove( r.data()+pos+1, r.data()+pos, (oldSize-pos)*sizeof( RenderTableCell * ) );
     489//              qDebug("moving from %d to %d, num=%d", pos, pos+1, (oldSize-pos-1) );
     490                r[pos+1] = r[pos] ? (RenderTableCell *)-1 : 0;
     491                row++;
    1862492            }
    1863493        }
    1864     }
    1865 
    1866     recalcColInfos();
    1867 }
     494        child = child->nextSibling();
     495    }
     496    columnPos.resize( numEffCols()+1 );
     497    setMinMaxKnown( false );
     498    setLayouted( false );
     499}
     500
     501void RenderTable::appendColumn( int span )
     502{
     503    // easy case.
     504    int pos = columns.size();
     505//     qDebug("appendColumn( %d ), size=%d", span, pos );
     506    int newSize = pos + 1;
     507    columns.resize( newSize );
     508    columns[pos].span = span;
     509    //qDebug("appending column at %d, span %d", pos,  span );
     510
     511    // change width of all rows.
     512    RenderObject *child = firstChild();
     513    while ( child ) {
     514        if ( child->isTableSection() ) {
     515            RenderTableSection *section = static_cast<RenderTableSection *>(child);
     516            int size = section->grid.size();
     517            int row = 0;
     518            while ( row < size ) {
     519                section->grid[row].row->resize( newSize );
     520                section->cellAt( row, pos ) = 0;
     521                row++;
     522            }
     523
     524        }
     525        child = child->nextSibling();
     526    }
     527    columnPos.resize( numEffCols()+1 );
     528    setMinMaxKnown( false );
     529    setLayouted( false );
     530}
     531
     532RenderTableCol *RenderTable::colElement( int col ) {
     533    if ( !has_col_elems )
     534        return 0;
     535    RenderObject *child = firstChild();
     536    int cCol = 0;
     537    while ( child ) {
     538        if ( child->isTableCol() ) {
     539            RenderTableCol *colElem = static_cast<RenderTableCol *>(child);
     540            int span = colElem->span();
     541            if ( !colElem->firstChild() ) {
     542                cCol += span;
     543                if ( cCol > col )
     544                    return colElem;
     545            }
     546
     547            RenderObject *next = child->firstChild();
     548            if ( !next )
     549                next = child->nextSibling();
     550            if ( !next && child->parent()->isTableCol() )
     551                next = child->parent()->nextSibling();
     552            child = next;
     553        } else
     554            break;
     555    }
     556    return 0;
     557}
     558
     559void RenderTable::recalcSections()
     560{
     561    tCaption = 0;
     562    head = foot = firstBody = 0;
     563    has_col_elems = false;
     564
     565    RenderObject *child = firstChild();
     566    // We need to get valid pointers to caption, head, foot and firstbody again
     567    while ( child ) {
     568        switch(child->style()->display()) {
     569        case TABLE_CAPTION:
     570            if ( !tCaption) {
     571                tCaption = static_cast<RenderFlow*>(child);
     572                tCaption->setLayouted(false);
     573            }
     574            break;
     575        case TABLE_COLUMN:
     576        case TABLE_COLUMN_GROUP:
     577            has_col_elems = true;
     578            return;
     579        case TABLE_HEADER_GROUP: {
     580            RenderTableSection *section = static_cast<RenderTableSection *>(child);
     581            if ( !head )
     582                head = section;
     583            else if ( !firstBody )
     584                firstBody = section;
     585            if ( section->needCellRecalc )
     586                section->recalcCells();
     587            break;
     588        }
     589        case TABLE_FOOTER_GROUP: {
     590            RenderTableSection *section = static_cast<RenderTableSection *>(child);
     591            if ( !foot )
     592                foot = section;
     593            else if ( !firstBody )
     594                firstBody = section;
     595            if ( section->needCellRecalc )
     596                section->recalcCells();
     597            break;
     598        }
     599        case TABLE_ROW_GROUP: {
     600            RenderTableSection *section = static_cast<RenderTableSection *>(child);
     601            if ( !firstBody )
     602                firstBody = section;
     603            if ( section->needCellRecalc )
     604                section->recalcCells();
     605        }
     606        default:
     607            break;
     608        }
     609        child = child->nextSibling();
     610    }
     611    needSectionRecalc = false;
     612    setLayouted( false );
     613}
     614
     615RenderObject* RenderTable::removeChildNode(RenderObject* child)
     616{
     617    setNeedSectionRecalc();
     618    return RenderContainer::removeChildNode( child );
     619}
     620
    1868621
    1869622#ifndef NDEBUG
    1870623void RenderTable::dump(QTextStream *stream, QString ind) const
    1871624{
    1872     *stream << " totalCols=" << totalCols;
    1873     *stream << " totalRows=" << totalRows;
    1874 
    1875625    if (tCaption)
    1876626        *stream << " tCaption";
     
    1880630        *stream << " foot";
    1881631
    1882     if (collapseBorders)
    1883         *stream << " collapseBorders";
    1884 
    1885 // ###    RenderTableCell ***cells;
    1886 // ###    QPtrVector<ColInfoLine> colInfos;
    1887 // ###    Frame frame;
    1888 // ###    Rules rules;
    1889 // ###    RenderTableCol *_oldColElem;
     632    *stream << endl << ind << "cspans:";
     633    for ( unsigned int i = 0; i < columns.size(); i++ )
     634        *stream << " " << columns[i].span;
     635    *stream << endl << ind;
    1890636
    1891637    RenderFlow::dump(stream,ind);
     
    1896642
    1897643RenderTableSection::RenderTableSection(DOM::NodeImpl* node)
    1898     : RenderContainer(node)
     644    : RenderBox(node)
    1899645{
    1900646    // init RenderObject attributes
    1901647    setInline(false);   // our object is not Inline
    1902     nrows = 0;
     648    cCol = 0;
     649    cRow = -1;
     650    needCellRecalc = false;
    1903651}
    1904652
    1905653RenderTableSection::~RenderTableSection()
     654{
     655    clearGrid();
     656}
     657
     658void RenderTableSection::detach(RenderArena* arena)
    1906659{
    1907660    // recalc cell info because RenderTable has unguarded pointers
    1908661    // stored that point to this RenderTableSection.
    1909     if (table)
    1910         table->setNeedsCellsRecalc();
     662    if (table())
     663        table()->setNeedSectionRecalc();
     664
     665    RenderBox::detach(arena);
     666}
     667
     668void RenderTableSection::setStyle(RenderStyle* _style)
     669{
     670    // we don't allow changing this one
     671    if (style())
     672        _style->setDisplay(style()->display());
     673    else if (_style->display() != TABLE_FOOTER_GROUP && _style->display() != TABLE_HEADER_GROUP)
     674        _style->setDisplay(TABLE_ROW_GROUP);
     675
     676    RenderBox::setStyle(_style);
    1911677}
    1912678
     
    1925691   
    1926692    if ( !child->isTableRow() ) {
     693
    1927694        if( !beforeChild )
    1928695            beforeChild = lastChild();
     
    1938705                return;
    1939706            } else {
    1940                 kdDebug( 6040 ) << "creating anonymous table row" << endl;
     707                //kdDebug( 6040 ) << "creating anonymous table row" << endl;
    1941708                row = new (renderArena()) RenderTableRow(0 /* anonymous table */);
    1942709                RenderStyle *newStyle = new RenderStyle();
    1943710                newStyle->inheritFrom(style());
    1944                 newStyle->setDisplay(TABLE_ROW);
     711                newStyle->setDisplay( TABLE_ROW );
    1945712                row->setStyle(newStyle);
    1946713                row->setIsAnonymousBox(true);
     
    1955722
    1956723    if (beforeChild)
    1957         table->setNeedsCellsRecalc();
    1958 
    1959     table->startRow();
    1960     child->setTable(table);
     724        setNeedCellRecalc();
     725
     726    cRow++;
     727    cCol = 0;
     728
     729    ensureRows( cRow+1 );
     730
     731    if (!beforeChild) {
     732        grid[cRow].height = child->style()->height();
     733        if ( grid[cRow].height.type == Relative )
     734            grid[cRow].height = Length();
     735    }
     736
     737
    1961738    RenderContainer::addChild(child,beforeChild);
     739}
     740
     741void RenderTableSection::ensureRows( int numRows )
     742{
     743    int nRows = grid.size();
     744    int nCols = table()->numEffCols();
     745    if ( numRows > nRows ) {
     746        grid.resize( numRows );
     747        for ( int r = nRows; r < numRows; r++ ) {
     748            grid[r].row = new Row( nCols );
     749            grid[r].row->fill( 0 );
     750            grid[r].baseLine = 0;
     751            grid[r].height = Length();
     752        }
     753    }
     754
     755}
     756
     757void RenderTableSection::addCell( RenderTableCell *cell )
     758{
     759    int rSpan = cell->rowSpan();
     760    int cSpan = cell->colSpan();
     761    QMemArray<RenderTable::ColumnStruct> &columns = table()->columns;
     762    int nCols = columns.size();
     763
     764    // ### mozilla still seems to do the old HTML way, even for strict DTD
     765    // (see the annotation on table cell layouting in the CSS specs and the testcase below:
     766    // <TABLE border>
     767    // <TR><TD>1 <TD rowspan="2">2 <TD>3 <TD>4
     768    // <TR><TD colspan="2">5
     769    // </TABLE>
     770#if 0
     771    // find empty space for the cell
     772    bool found = false;
     773    while ( !found ) {
     774        found = true;
     775        while ( cCol < nCols && cellAt( cRow, cCol ) )
     776            cCol++;
     777        int pos = cCol;
     778        int span = 0;
     779        while ( pos < nCols && span < cSpan ) {
     780            if ( cellAt( cRow, pos ) ) {
     781                found = false;
     782                cCol = pos;
     783                break;
     784            }
     785            span += columns[pos].span;
     786            pos++;
     787        }
     788    }
     789#else
     790    while ( cCol < nCols && cellAt( cRow, cCol ) )
     791        cCol++;
     792#endif
     793
     794//       qDebug("adding cell at %d/%d span=(%d/%d)",  cRow, cCol, rSpan, cSpan );
     795
     796    if ( rSpan == 1 ) {
     797        // we ignore height settings on rowspan cells
     798        Length height = cell->style()->height();
     799        if ( height.value > 0 || (height.type == Relative && height.value >= 0) ) {
     800            Length cRowHeight = grid[cRow].height;
     801            switch( height.type ) {
     802            case Percent:
     803                if ( !(cRowHeight.type == Percent) ||
     804                     ( cRowHeight.type == Percent && cRowHeight.value < height.value ) )
     805                    grid[cRow].height = height;
     806                     break;
     807            case Fixed:
     808                if ( cRowHeight.type < Percent ||
     809                     ( cRowHeight.type == Fixed && cRowHeight.value < height.value ) )
     810                    grid[cRow].height = height;
     811                break;
     812            case Relative:
     813#if 0
     814                // we treat this as variable. This is correct according to HTML4, as it only specifies length for the height.
     815                if ( cRowHeight.type == Variable ||
     816                     ( cRowHeight.type == Relative && cRowHeight.value < height.value ) )
     817                     grid[cRow].height = height;
     818                     break;
     819#endif
     820            default:
     821                break;
     822            }
     823        }
     824    }
     825
     826    // make sure we have enough rows
     827    ensureRows( cRow + rSpan );
     828
     829    int col = cCol;
     830    // tell the cell where it is
     831    RenderTableCell *set = cell;
     832    while ( cSpan ) {
     833        int currentSpan;
     834        if ( cCol >= nCols ) {
     835            table()->appendColumn( cSpan );
     836            currentSpan = cSpan;
     837        } else {
     838            if ( cSpan < columns[cCol].span )
     839                table()->splitColumn( cCol, cSpan );
     840            currentSpan = columns[cCol].span;
     841        }
     842        int r = 0;
     843        while ( r < rSpan ) {
     844            if ( !cellAt( cRow + r, cCol ) ) {
     845//              qDebug("    adding cell at %d, %d",  cRow + r, cCol );
     846                cellAt( cRow + r, cCol ) = set;
     847            }
     848            r++;
     849        }
     850        cCol++;
     851        cSpan -= currentSpan;
     852        set = (RenderTableCell *)-1;
     853    }
     854    if ( cell ) {
     855        cell->setRow( cRow );
     856        cell->setCol( table()->effColToCol( col ) );
     857    }
     858}
     859
     860
     861
     862void RenderTableSection::setCellWidths()
     863{
     864#ifdef DEBUG_LAYOUT
     865    kdDebug( 6040 ) << renderName() << "(Table, this=0x" << this << ")::setCellWidths()" << endl;
     866#endif
     867    QMemArray<int> &columnPos = table()->columnPos;
     868
     869    int rows = grid.size();
     870    for ( int i = 0; i < rows; i++ ) {
     871        Row &row = *grid[i].row;
     872        int cols = row.size();
     873        for ( int j = 0; j < cols; j++ ) {
     874            RenderTableCell *cell = row[j];
     875//          qDebug("cell[%d,%d] = %p", i, j, cell );
     876            if ( !cell || cell == (RenderTableCell *)-1 )
     877                continue;
     878            int endCol = j;
     879            int cspan = cell->colSpan();
     880            while ( cspan && endCol < cols ) {
     881                cspan -= table()->columns[endCol].span;
     882                endCol++;
     883            }
     884            int w = columnPos[endCol] - columnPos[j] - table()->cellSpacing();
     885#ifdef DEBUG_LAYOUT
     886            kdDebug( 6040 ) << "setting width of cell " << cell << " " << cell->row() << "/" << cell->col() << " to " << w << " colspan=" << cell->colSpan() << " start=" << j << " end=" << endCol << endl;
     887#endif
     888            int oldWidth = cell->width();
     889            if ( w != oldWidth ) {
     890                cell->setLayouted(false);
     891                cell->setWidth( w );
     892            }
     893        }
     894    }
     895}
     896
     897
     898void RenderTableSection::calcRowHeight()
     899{
     900    int indx;
     901    RenderTableCell *cell;
     902
     903    int totalRows = grid.size();
     904    int spacing = table()->cellSpacing();
     905
     906    rowPos.resize( totalRows + 1 );
     907    rowPos[0] =  spacing + borderTop();
     908
     909    for ( int r = 0; r < totalRows; r++ ) {
     910        rowPos[r+1] = 0;
     911
     912        int baseline=0;
     913        int bdesc = 0;
     914//      qDebug("height of row %d is %d/%d", r, grid[r].height.value, grid[r].height.type );
     915        int ch = grid[r].height.minWidth( 0 );
     916        int pos = rowPos[ r+1 ] + ch + table()->cellSpacing();
     917
     918        if ( pos > rowPos[r+1] )
     919            rowPos[r+1] = pos;
     920
     921        Row *row = grid[r].row;
     922        int totalCols = row->size();
     923        int totalRows = grid.size();
     924
     925        for ( int c = 0; c < totalCols; c++ ) {
     926            cell = cellAt(r, c);
     927            if ( !cell || cell == (RenderTableCell *)-1 )
     928                continue;
     929            if ( r < totalRows - 1 && cellAt(r+1, c) == cell )
     930                continue;
     931
     932            if ( ( indx = r - cell->rowSpan() + 1 ) < 0 )
     933                indx = 0;
     934
     935            ch = cell->style()->height().width(0);
     936            if ( cell->height() > ch)
     937                ch = cell->height();
     938
     939            pos = rowPos[ indx ] + ch + table()->cellSpacing();
     940
     941            if ( pos > rowPos[r+1] )
     942                rowPos[r+1] = pos;
     943
     944            // find out the baseline
     945            EVerticalAlign va = cell->style()->verticalAlign();
     946            if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP
     947                || va == SUPER || va == SUB)
     948            {
     949                int b=cell->baselinePosition();
     950
     951                if (b>baseline)
     952                    baseline=b;
     953
     954                int td = rowPos[ indx ] + ch - b;
     955                if (td>bdesc)
     956                    bdesc = td;
     957            }
     958        }
     959
     960        //do we have baseline aligned elements?
     961        if (baseline) {
     962            // increase rowheight if baseline requires
     963            int bRowPos = baseline + bdesc  + table()->cellSpacing() ; // + 2*padding
     964            if (rowPos[r+1]<bRowPos)
     965                rowPos[r+1]=bRowPos;
     966
     967            grid[r].baseLine = baseline;
     968        }
     969
     970        if ( rowPos[r+1] < rowPos[r] )
     971            rowPos[r+1] = rowPos[r];
     972//      qDebug("rowpos(%d)=%d",  r, rowPos[r] );
     973    }
     974}
     975
     976int RenderTableSection::layoutRows( int toAdd )
     977{
     978    int rHeight;
     979    int rindx;
     980    int totalRows = grid.size();
     981    int spacing = table()->cellSpacing();
     982
     983    if (toAdd && totalRows && rowPos[totalRows]) {
     984
     985        int totalHeight = rowPos[totalRows] + toAdd;
     986//      qDebug("layoutRows: totalHeight = %d",  totalHeight );
     987
     988        int dh = totalHeight-rowPos[totalRows];
     989        int totalPercent = 0;
     990        int numVariable = 0;
     991        for ( int r = 0; r < totalRows; r++ ) {
     992            if ( grid[r].height.type == Variable )
     993                numVariable++;
     994            else if ( grid[r].height.type == Percent )
     995                totalPercent += grid[r].height.value;
     996        }
     997        if ( totalPercent ) {
     998//          qDebug("distributing %d over percent rows totalPercent=%d", dh,  totalPercent );
     999            // try to satisfy percent
     1000            int add = 0;
     1001            if ( totalPercent > 100 )
     1002                totalPercent = 100;
     1003            int rh = rowPos[1]-rowPos[0];
     1004            for ( int r = 0; r < totalRows; r++ ) {
     1005                if ( totalPercent > 0 && grid[r].height.type == Percent ) {
     1006                    int toAdd = QMIN( dh, (totalHeight * grid[r].height.value / 100)-rh );
     1007                    add += toAdd;
     1008                    dh -= toAdd;
     1009                    totalPercent -= grid[r].height.value;
     1010//                  qDebug( "adding %d to row %d", toAdd, r );
     1011                }
     1012                if ( r < totalRows-1 )
     1013                    rh = rowPos[r+2] - rowPos[r+1];
     1014                rowPos[r+1] += add;
     1015            }
     1016        }
     1017        if ( numVariable ) {
     1018            // distribute over variable cols
     1019//          qDebug("distributing %d over variable rows numVariable=%d", dh,  numVariable );
     1020            int add = 0;
     1021            for ( int r = 0; r < totalRows; r++ ) {
     1022                if ( numVariable > 0 && grid[r].height.type == Variable ) {
     1023                    int toAdd = dh/numVariable;
     1024                    add += toAdd;
     1025                    dh -= toAdd;
     1026                }
     1027                rowPos[r+1] += add;
     1028            }
     1029        }
     1030        if (dh>0) {
     1031            // if some left overs, distribute equally.
     1032            int tot=rowPos[totalRows];
     1033            int add=0;
     1034            int prev=rowPos[0];
     1035            for ( int r = 0; r < totalRows; r++ ) {
     1036                //weight with the original height
     1037                add+=dh*(rowPos[r+1]-prev)/tot;
     1038                prev=rowPos[r+1];
     1039                rowPos[r+1]+=add;
     1040            }
     1041        }
     1042    }
     1043
     1044    int leftOffset = borderLeft() + spacing;
     1045
     1046    int nEffCols = table()->numEffCols();
     1047    for ( int r = 0; r < totalRows; r++ )
     1048    {
     1049        Row *row = grid[r].row;
     1050        int totalCols = row->size();
     1051        for ( int c = 0; c < nEffCols; c++ )
     1052        {
     1053            RenderTableCell *cell = cellAt(r, c);
     1054            if (!cell || cell == (RenderTableCell *)-1 )
     1055                continue;
     1056            if ( r < totalRows - 1 && cell == cellAt(r+1, c) )
     1057                continue;
     1058
     1059            if ( ( rindx = r-cell->rowSpan()+1 ) < 0 )
     1060                rindx = 0;
     1061
     1062            rHeight = rowPos[r+1] - rowPos[rindx] - spacing;
     1063           
     1064            // Force percent height children to lay themselves out again.
     1065            // This will cause, e.g., textareas to grow to
     1066            // fill the area.  FIXME: <div>s and blocks still don't
     1067            // work right.  We'll need to have an efficient way of
     1068            // invalidating all percent height objects in a render subtree.
     1069            // For now, we just handle immediate children. -dwh
     1070            bool cellChildrenFlex = false;
     1071            RenderObject* o = cell->firstChild();
     1072            while (o) {
     1073                if (o->style()->height().isPercent()) {
     1074                    o->setLayouted(false);
     1075                    cellChildrenFlex = true;
     1076                }
     1077                o = o->nextSibling();
     1078            }
     1079            if (cellChildrenFlex) {
     1080                cell->setCellPercentageHeight(rHeight);
     1081                cell->layout();
     1082           
     1083                // Alignment within a cell is based off the calculated
     1084                // height, which becomes irrelevant once the cell has
     1085                // been resized based off its percentage. -dwh
     1086                cell->setCellTopExtra(0);
     1087                cell->setCellBottomExtra(0);
     1088            }
     1089            else {
     1090#ifdef DEBUG_LAYOUT
     1091            kdDebug( 6040 ) << "setting position " << r << "/" << c << ": "
     1092                            << table()->columnPos[c] /*+ padding */ << "/" << rowPos[rindx] << " height=" << rHeight<< endl;
     1093#endif
     1094
     1095            EVerticalAlign va = cell->style()->verticalAlign();
     1096            int te=0;
     1097            switch (va)
     1098            {
     1099            case SUB:
     1100            case SUPER:
     1101            case TEXT_TOP:
     1102            case TEXT_BOTTOM:
     1103            case BASELINE:
     1104                te = getBaseline(r) - cell->baselinePosition() ;
     1105                break;
     1106            case TOP:
     1107                te = 0;
     1108                break;
     1109            case MIDDLE:
     1110                te = (rHeight - cell->height())/2;
     1111                break;
     1112            case BOTTOM:
     1113                te = rHeight - cell->height();
     1114                break;
     1115            default:
     1116                break;
     1117            }
     1118#ifdef DEBUG_LAYOUT
     1119            //            kdDebug( 6040 ) << "CELL " << cell << " te=" << te << ", be=" << rHeight - cell->height() - te << ", rHeight=" << rHeight << ", valign=" << va << endl;
     1120#endif
     1121            cell->setCellTopExtra( te );
     1122            cell->setCellBottomExtra( rHeight - cell->height() - te);
     1123            }
     1124           
     1125            if (style()->direction()==RTL) {
     1126                cell->setPos(
     1127                    table()->columnPos[(int)totalCols] -
     1128                    table()->columnPos[table()->colToEffCol(cell->col()+cell->colSpan())] +
     1129                    leftOffset,
     1130                    rowPos[rindx] );
     1131            } else {
     1132                cell->setPos( table()->columnPos[c] + leftOffset, rowPos[rindx] );
     1133            }
     1134        }
     1135    }
     1136
     1137    m_height = rowPos[totalRows];
     1138    return m_height;
     1139}
     1140
     1141
     1142void RenderTableSection::paint( QPainter *p, int x, int y, int w, int h,
     1143                                int tx, int ty, int paintPhase)
     1144{
     1145    unsigned int totalRows = grid.size();
     1146    unsigned int totalCols = table()->columns.size();
     1147
     1148    tx += m_x;
     1149    ty += m_y;
     1150
     1151    // check which rows and cols are visible and only paint these
     1152    // ### fixme: could use a binary search here
     1153    unsigned int startrow = 0;
     1154    unsigned int endrow = totalRows;
     1155    for ( ; startrow < totalRows; startrow++ ) {
     1156        if ( ty + rowPos[startrow+1] > y )
     1157            break;
     1158    }
     1159    for ( ; endrow > 0; endrow-- ) {
     1160        if ( ty + rowPos[endrow-1] < y + h )
     1161            break;
     1162    }
     1163    unsigned int startcol = 0;
     1164    unsigned int endcol = totalCols;
     1165    if ( style()->direction() == LTR ) {
     1166        for ( ; startcol < totalCols; startcol++ ) {
     1167            if ( tx + table()->columnPos[startcol+1] > x )
     1168                break;
     1169        }
     1170        for ( ; endcol > 0; endcol-- ) {
     1171            if ( tx + table()->columnPos[endcol-1] < x + w )
     1172                break;
     1173        }
     1174    }
     1175    if ( startcol < endcol ) {
     1176        // draw the cells
     1177        for ( unsigned int r = startrow; r < endrow; r++ ) {
     1178            unsigned int c = startcol;
     1179            // since a cell can be -1 (indicating a colspan) we might have to search backwards to include it
     1180            while ( c && cellAt( r, c ) == (RenderTableCell *)-1 )
     1181                c--;
     1182            for ( ; c < endcol; c++ ) {
     1183                RenderTableCell *cell = cellAt(r, c);
     1184                if (!cell || cell == (RenderTableCell *)-1 )
     1185                    continue;
     1186                if ( (r < endrow - 1) && (cellAt(r+1, c) == cell) )
     1187                    continue;
     1188
     1189#ifdef TABLE_PRINT
     1190                kdDebug( 6040 ) << "painting cell " << r << "/" << c << endl;
     1191#endif
     1192                cell->paint( p, x, y, w, h, tx, ty, paintPhase);
     1193            }
     1194        }
     1195    }
     1196}
     1197
     1198void RenderTableSection::recalcCells()
     1199{
     1200    cCol = 0;
     1201    cRow = -1;
     1202    clearGrid();
     1203    grid.resize( 0 );
     1204
     1205    RenderObject *row = firstChild();
     1206    while ( row ) {
     1207        cRow++;
     1208        cCol = 0;
     1209        ensureRows( cRow+1 );
     1210        RenderObject *cell = row->firstChild();
     1211        while ( cell ) {
     1212            if ( cell->isTableCell() )
     1213                addCell( static_cast<RenderTableCell *>(cell) );
     1214            cell = cell->nextSibling();
     1215        }
     1216        row = row->nextSibling();
     1217    }
     1218    needCellRecalc = false;
     1219    setLayouted( false );
     1220}
     1221
     1222void RenderTableSection::clearGrid()
     1223{
     1224    int rows = grid.size();
     1225    while ( rows-- ) {
     1226        delete grid[rows].row;
     1227    }
     1228}
     1229
     1230RenderObject* RenderTableSection::removeChildNode(RenderObject* child)
     1231{
     1232    setNeedCellRecalc();
     1233    return RenderContainer::removeChildNode( child );
    19621234}
    19631235
     
    19651237void RenderTableSection::dump(QTextStream *stream, QString ind) const
    19661238{
    1967     *stream << " nrows=" << nrows;
    1968 
     1239    *stream << endl << ind << "grid=(" << grid.size() << "," << table()->numEffCols() << ")" << endl << ind;
     1240    for ( unsigned int r = 0; r < grid.size(); r++ ) {
     1241        for ( int c = 0; c < table()->numEffCols(); c++ ) {
     1242            if ( cellAt( r,  c ) && cellAt( r, c ) != (RenderTableCell *)-1 )
     1243                *stream << "(" << cellAt( r, c )->row() << "," << cellAt( r, c )->col() << ","
     1244                        << cellAt(r, c)->rowSpan() << "," << cellAt(r, c)->colSpan() << ") ";
     1245            else
     1246                *stream << cellAt( r, c ) << "null cell ";
     1247        }
     1248        *stream << endl << ind;
     1249    }
    19691250    RenderContainer::dump(stream,ind);
    19701251}
     
    19781259    // init RenderObject attributes
    19791260    setInline(false);   // our object is not Inline
    1980 
    1981     rIndex = -1;
    1982     ncols = 0;
    1983 }
    1984 
    1985 RenderTableRow::~RenderTableRow()
    1986 {
    1987     if (table)
    1988         table->setNeedsCellsRecalc();
    1989 }
    1990 
    1991 
    1992 long RenderTableRow::rowIndex() const
    1993 {
    1994     // ###
    1995     return 0;
    1996 }
    1997 
    1998 void RenderTableRow::setRowIndex( long  )
    1999 {
    2000     // ###
    2001 }
    2002 
    2003 void RenderTableRow::close()
    2004 {
    2005     table->closeRow();
    2006     RenderContainer::close();
     1261}
     1262
     1263void RenderTableRow::detach(RenderArena* arena)
     1264{
     1265    section()->setNeedCellRecalc();
     1266
     1267    RenderContainer::detach(arena);
     1268}
     1269
     1270void RenderTableRow::setStyle(RenderStyle* style)
     1271{
     1272    style->setDisplay(TABLE_ROW);
     1273    RenderContainer::setStyle(style);
    20071274}
    20081275
     
    20131280                       (beforeChild ? beforeChild->renderName() : "0") << " )" << endl;
    20141281#endif
    2015     RenderTableCell *cell;
    2016 
    20171282    if (child->element() && child->element()->id() == ID_FORM) {
    20181283        RenderContainer::addChild(child,beforeChild);
     
    20201285    }
    20211286
     1287    RenderTableCell *cell;
     1288
    20221289    if ( !child->isTableCell() ) {
    2023         if ( !beforeChild )
    2024             beforeChild = lastChild();
    2025         RenderTableCell *cell;
    2026         if( beforeChild && beforeChild->isAnonymousBox() && beforeChild->isTableCell() )
    2027             cell = static_cast<RenderTableCell *>(beforeChild);
     1290        RenderObject *last = beforeChild;
     1291        if ( !last )
     1292            last = lastChild();
     1293        RenderTableCell *cell = 0;
     1294        if( last && last->isAnonymousBox() && last->isTableCell() )
     1295            cell = static_cast<RenderTableCell *>(last);
    20281296        else {
    2029             RenderObject *lastBox = beforeChild;
    2030             while ( lastBox && lastBox->parent()->isAnonymousBox() && !lastBox->isTableCell() )
    2031                 lastBox = lastBox->parent();
    2032             if ( lastBox && lastBox->isAnonymousBox() ) {
    2033                 lastBox->addChild( child, beforeChild );
    2034                 return;
    2035             } else {
    2036 //          kdDebug( 6040 ) << "creating anonymous table cell" << endl;
    2037                 cell = new (renderArena()) RenderTableCell(0 /* anonymous object */);
    2038                 RenderStyle *newStyle = new RenderStyle();
    2039                 newStyle->inheritFrom(style());
    2040                 newStyle->setDisplay(TABLE_CELL);
    2041                 cell->setStyle(newStyle);
    2042                 cell->setIsAnonymousBox(true);
    2043                 addChild(cell, beforeChild);
    2044             }
     1297            cell = new (renderArena()) RenderTableCell(0 /* anonymous object */);
     1298            RenderStyle *newStyle = new RenderStyle();
     1299            newStyle->inheritFrom(style());
     1300            newStyle->setDisplay( TABLE_CELL );
     1301            cell->setStyle(newStyle);
     1302            cell->setIsAnonymousBox(true);
     1303            addChild(cell, beforeChild);
    20451304        }
    20461305        cell->addChild(child);
     
    20511310        cell = static_cast<RenderTableCell *>(child);
    20521311
    2053     cell->setTable(table);
    2054     cell->setRowImpl(this);
    2055     table->addCell(cell);  // ### may not work for beforeChild != 0
     1312    static_cast<RenderTableSection *>(parent())->addCell( cell );
    20561313
    20571314    RenderContainer::addChild(cell,beforeChild);
    20581315
    2059     if (beforeChild || nextSibling())
    2060         table->setNeedsCellsRecalc();
    2061 
    2062 }
    2063 
    2064 void RenderTableRow::repaint(bool immediate)
    2065 {
    2066     if ( table ) table->repaint(immediate);
     1316    if ( ( beforeChild || nextSibling()) && section() )
     1317        section()->setNeedCellRecalc();
     1318}
     1319
     1320RenderObject* RenderTableRow::removeChildNode(RenderObject* child)
     1321{
     1322// RenderTableCell detach should do it
     1323//     if ( section() )
     1324//      section()->setNeedCellRecalc();
     1325    return RenderContainer::removeChildNode( child );
    20671326}
    20681327
     
    20701329void RenderTableRow::dump(QTextStream *stream, QString ind) const
    20711330{
    2072     *stream << " rIndex = " << rIndex;
    2073     *stream << " ncols = " << ncols;
    2074 
    20751331    RenderContainer::dump(stream,ind);
    20761332}
     
    20841340    RenderObject *child = firstChild();
    20851341    while( child ) {
    2086         if (child->isTableCell() && !child->layouted() ) {
    2087             RenderTableCell *cell = static_cast<RenderTableCell *>(child);
    2088             cell->calcVerticalMargins();
    2089             cell->layout();
    2090             cell->setCellTopExtra(0);
    2091             cell->setCellBottomExtra(0);
    2092         }
    2093         child = child->nextSibling();
     1342        if ( child->isTableCell() && !child->layouted() ) {
     1343            RenderTableCell *cell = static_cast<RenderTableCell *>(child);
     1344            cell->calcVerticalMargins();
     1345            cell->layout();
     1346            cell->setCellTopExtra(0);
     1347            cell->setCellBottomExtra(0);
     1348        }
     1349        child = child->nextSibling();
    20941350    }
    20951351    setLayouted();
     
    21041360  _row = -1;
    21051361  updateFromElement();
    2106   _id = 0;
    2107   rowHeight = 0;
    2108   cellPercentageHeight = 0;
    2109   m_table = 0;
    2110   rowimpl = 0;
    21111362  setShouldPaintBackgroundOrBorder(true);
    21121363  _topExtra = 0;
    21131364  _bottomExtra = 0;
    2114 }
    2115 
    2116 RenderTableCell::~RenderTableCell()
    2117 {
    2118     if (m_table)
    2119         m_table->setNeedsCellsRecalc();
     1365  m_percentageHeight = 0;
     1366}
     1367
     1368void RenderTableCell::detach(RenderArena* arena)
     1369{
     1370    if (parent() && section())
     1371        section()->setNeedCellRecalc();
     1372
     1373    RenderFlow::detach(arena);
    21201374}
    21211375
     
    21271381      cSpan = tc->colSpan();
    21281382      rSpan = tc->rowSpan();
    2129       nWrap = tc->noWrap();
    21301383  } else {
    21311384      cSpan = rSpan = 1;
    2132       nWrap = false;
    21331385  }
    21341386}
    21351387
     1388int RenderTableCell::getCellPercentageHeight() const
     1389{
     1390    return m_percentageHeight;
     1391}
     1392
     1393void RenderTableCell::setCellPercentageHeight(int h)
     1394{
     1395    m_percentageHeight = h;
     1396}
     1397   
    21361398void RenderTableCell::calcMinMaxWidth()
    21371399{
     
    21411403#endif
    21421404
    2143     //if(minMaxKnown()) return;
    2144 
    2145     int oldMin = m_minWidth;
    2146     int oldMax = m_maxWidth;
    2147 
    21481405    RenderFlow::calcMinMaxWidth();
    2149 
    2150     // NOWRAP Should apply even in cases where the width is fixed.  Consider the following
    2151     // test case.
    2152     // <table border="1">
    2153     // <tr>
    2154     // <td width="175">Check this text out. It shouldn't shrink below 300px.</td>
    2155     // <td width="100%"></td>
    2156     // </tr>
    2157     // <tr><td width="300" nowrap></tr>
    2158     // </table>
    2159     // The width of the cell should not be allowed to fall below the max width of the column when
    2160     // nowrap is enabled on any cell in the column.  - dwh
    2161     if(nWrap)
    2162         m_minWidth = m_maxWidth;
    2163 
    2164     if (m_minWidth!=oldMin || m_maxWidth!=oldMax) {
    2165         m_table->addColInfo(this);
    2166     }
     1406   
    21671407    setMinMaxKnown();
    21681408}
     
    21891429}
    21901430
    2191 int RenderTableCell::paddingTop() const
    2192 {
    2193     if (style()->hasPadding())
    2194         return RenderFlow::paddingTop();
    2195     if (m_table && m_table->cellPadding() != -1)
    2196         return m_table->cellPadding();
    2197     return 0;
    2198 }
    2199 
    2200 int RenderTableCell::paddingBottom() const
    2201 {
    2202     if (style()->hasPadding())
    2203         return RenderFlow::paddingBottom();
    2204     if (m_table && m_table->cellPadding() != -1)
    2205         return m_table->cellPadding();
    2206     return 0;
    2207 }
    2208 
    2209 int RenderTableCell::paddingLeft() const
    2210 {
    2211     if (style()->hasPadding())
    2212         return RenderFlow::paddingLeft();
    2213     if (m_table && m_table->cellPadding() != -1)
    2214         return m_table->cellPadding();
    2215     return 0;
    2216 }
    2217 
    2218 int RenderTableCell::paddingRight() const
    2219 {
    2220     if (style()->hasPadding())
    2221         return RenderFlow::paddingRight();
    2222     if (m_table && m_table->cellPadding() != -1)
    2223         return m_table->cellPadding();
    2224     return 0;
    2225 }
    22261431
    22271432void RenderTableCell::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f)
     
    22421447{
    22431448    RenderObject *o = firstChild();
    2244     int offset = paddingTop();
     1449    int offset = paddingTop() + borderTop();
    22451450    if ( !o ) return offset;
    22461451    while ( o->firstChild() ) {
    2247         offset += paddingTop() + borderTop();
     1452        if ( !o->isInline() )
     1453            offset += o->paddingTop() + o->borderTop();
    22481454        o = o->firstChild();
    22491455    }
     
    22551461void RenderTableCell::setStyle( RenderStyle *style )
    22561462{
     1463    style->setDisplay(TABLE_CELL);
    22571464    RenderFlow::setStyle( style );
    22581465    setShouldPaintBackgroundOrBorder(true);
     1466   
     1467    if (style->whiteSpace() == KONQ_NOWRAP) {
     1468        // Figure out if we are really nowrapping or if we should just
     1469        // use normal instead.  If the width of the cell is fixed, then
     1470        // we don't actually use NOWRAP.
     1471        if (style->width().isFixed())
     1472            style->setWhiteSpace(NORMAL);
     1473        else
     1474            style->setWhiteSpace(NOWRAP);
     1475    }
    22591476}
    22601477
     
    22711488
    22721489void RenderTableCell::paint(QPainter *p, int _x, int _y,
    2273                             int _w, int _h, int _tx, int _ty, int paintPhase)
     1490                                       int _w, int _h, int _tx, int _ty, int paintPhase)
    22741491{
    22751492
    22761493#ifdef TABLE_PRINT
    2277     kdDebug( 6040 ) << renderName() << "(RenderTableCell)::paint() w/h = (" << width() << "/" << height() << ")" << endl;
    2278 #endif
    2279 
    2280 //    if (!layouted())
    2281 //      return;
     1494    kdDebug( 6040 ) << renderName() << "(RenderTableCell)::paint() w/h = (" << width() << "/" << height() << ")" << " _y/_h=" << _y << "/" << _h << endl;
     1495#endif
     1496
     1497    if (!layouted()) return;
    22821498
    22831499    _tx += m_x;
     
    22971513
    22981514void RenderTableCell::paintBoxDecorations(QPainter *p,int, int _y,
    2299                                           int, int _h, int _tx, int _ty)
    2300 {
    2301     //kdDebug( 6040 ) << renderName() << "::paintBoxDecorations()" << endl;
    2302 
     1515                                       int, int _h, int _tx, int _ty)
     1516{
    23031517    int w = width();
    23041518    int h = height() + borderTopExtra() + borderBottomExtra();
    23051519    _ty -= borderTopExtra();
    2306 
    2307     int my = KMAX(_ty,_y);
    2308     int mh;
    2309     if (_ty<_y)
    2310         mh= KMAX(0,h-(_y-_ty));
    2311     else
    2312         mh = KMIN(_h,h);
    23131520
    23141521    QColor c = style()->backgroundColor();
     
    23171524    if ( !c.isValid() && parent() && parent()->parent() ) // take from rowgroup
    23181525        c = parent()->parent()->style()->backgroundColor();
    2319     // ### col is missing...
     1526    if ( !c.isValid() ) {
     1527        // see if we have a col or colgroup for this
     1528        RenderTableCol *col = table()->colElement( _col );
     1529        if ( col ) {
     1530            c = col->style()->backgroundColor();
     1531            if ( !c.isValid() ) {
     1532                // try column group
     1533                RenderStyle *style = col->parent()->style();
     1534                if ( style->display() == TABLE_COLUMN_GROUP )
     1535                    c = style->backgroundColor();
     1536            }
     1537        }
     1538    }
    23201539
    23211540    // ### get offsets right in case the bgimage is inherited.
     
    23251544    if ( !bg && parent() && parent()->parent() )
    23261545        bg = parent()->parent()->style()->backgroundImage();
     1546    if ( !bg ) {
     1547        // see if we have a col or colgroup for this
     1548        RenderTableCol *col = table()->colElement( _col );
     1549        if ( col ) {
     1550            bg = col->style()->backgroundImage();
     1551            if ( !bg ) {
     1552                // try column group
     1553                RenderStyle *style = col->parent()->style();
     1554                if ( style->display() == TABLE_COLUMN_GROUP )
     1555                    bg = style->backgroundImage();
     1556            }
     1557        }
     1558    }
     1559
     1560    int my = QMAX(_ty,_y);
     1561    int end = QMIN( _y + _h,  _ty + h );
     1562    int mh = end - my;
    23271563
    23281564    if ( bg || c.isValid() )
    2329         paintBackground(p, c, bg, my, mh, _tx, _ty, w, h);
     1565        paintBackground(p, c, bg, my, mh, _tx, _ty, w, h);
    23301566
    23311567    if(style()->hasBorder())
     
    23331569}
    23341570
    2335 void RenderTableCell::repaint(bool immediate)
    2336 {
    2337     // XXXdwh WHY? This just causes way too much repainting!
    2338     //if ( m_table ) m_table->repaint(immediate);
    2339     return RenderFlow::repaint(immediate);
    2340 }
    23411571
    23421572#ifndef NDEBUG
    23431573void RenderTableCell::dump(QTextStream *stream, QString ind) const
    23441574{
    2345     *stream << " _row=" << _row;
    2346     *stream << " _col=" << _col;
     1575    *stream << " row=" << _row;
     1576    *stream << " col=" << _col;
    23471577    *stream << " rSpan=" << rSpan;
    23481578    *stream << " cSpan=" << cSpan;
    2349     *stream << " _id=" << _id;
    2350     *stream << " nWrap=" << nWrap;
     1579//    *stream << " nWrap=" << nWrap;
    23511580
    23521581    RenderFlow::dump(stream,ind);
     
    23641593    _span = 1;
    23651594    updateFromElement();
    2366     _currentCol = 0;
    2367     _startCol = 0;
    2368     _id = 0;
    2369 }
    2370 
    2371 RenderTableCol::~RenderTableCol()
    2372 {
    23731595}
    23741596
     
    23791601      DOM::HTMLTableColElementImpl *tc = static_cast<DOM::HTMLTableColElementImpl *>(node);
    23801602      _span = tc->span();
    2381   } else {
    2382       if ( style()->display() == TABLE_COLUMN_GROUP )
    2383           _span = 0;
    2384       else
    2385           _span = 1;
    2386   }
     1603  } else
     1604      _span = ! ( style() && style()->display() == TABLE_COLUMN_GROUP );
    23871605}
    23881606
     
    23951613
    23961614    if (child->style()->display() == TABLE_COLUMN)
    2397     {
    23981615        // these have to come before the table definition!
    23991616        RenderContainer::addChild(child,beforeChild);
    2400         RenderTableCol* colel = static_cast<RenderTableCol *>(child);
    2401         colel->setStartCol(_currentCol);
    2402 //      kdDebug( 6040 ) << "_currentCol=" << _currentCol << endl;
    2403         table->addColInfo(colel);
    2404         _currentCol++;
    2405     }
    24061617}
    24071618
     
    24101621{
    24111622    *stream << " _span=" << _span;
    2412     *stream << " _startCol=" << _startCol;
    2413     *stream << " _id=" << _id;
    2414 
    24151623    RenderContainer::dump(stream,ind);
    24161624}
    24171625#endif
    2418 
    2419 // -------------------------------------------------------------------------
    2420 
    2421 RenderTableCaption::RenderTableCaption(DOM::NodeImpl* node)
    2422   : RenderFlow(node)
    2423 {
    2424 }
    2425 
    2426 RenderTableCaption::~RenderTableCaption()
    2427 {
    2428 }
    24291626
    24301627#undef TABLE_DEBUG
  • trunk/WebCore/khtml/rendering/render_table.h

    r3143 r3351  
    77 *           (C) 1999 Lars Knoll (knoll@kde.org)
    88 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    9  * Copyright (C) 2002 Apple Computer, Inc.
    109 *
    1110 * This library is free software; you can redistribute it and/or
     
    2423 * Boston, MA 02111-1307, USA.
    2524 *
     25 * $Id$
    2626 */
    2727#ifndef RENDER_TABLE_H
     
    4747class RenderTableCell;
    4848class RenderTableCol;
    49 class RenderTableCaption;
     49class TableLayout;
    5050
    5151class RenderTable : public RenderFlow
     
    8282    virtual bool isTable() const { return true; }
    8383
    84     int getColumnPos(int col)
     84    int getColumnPos(int col) const
    8585        { return columnPos[col]; }
    86     int getColumnWidth(int col)
    87         { if(!actColWidth.size() < col) return 0; return actColWidth[col]; }
    88 
    89     int cellSpacing() { return spacing; }
    90 
    91     Rules getRules() { return rules; }
    92 
    93     QColor bgColor() { return style()->backgroundColor(); }
    94 
    95 
    96     void startRow();
    97     void addCell( RenderTableCell *cell );
    98     void endTable();
    99     void  addColInfo(RenderTableCell *cell, bool recalc = true);
    100     void  addColInfo(RenderTableCol *colel);
    101 
    102     void addColInfo(int _startCol, int _colSpan,
    103                     int _minSize, int _maxSize, khtml::Length _width,
    104                     RenderTableCell* _cell, bool recalc = true);
    105 
    106     void recalcColInfos();
     86
     87    int cellSpacing() const { return spacing; }
     88
     89    Rules getRules() const { return rules; }
     90
     91    const QColor &bgColor() const { return style()->backgroundColor(); }
     92
     93    uint cellPadding() const { return padding; }
     94    void setCellPadding( uint p ) { padding = p; }
    10795
    10896    // overrides
     
    11098    virtual int overflowWidth() const { return width(); }
    11199    virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
    112     virtual void paint(QPainter *, int x, int y, int w, int h,
    113                        int tx, int ty, int paintPhase);
     100    virtual void paint( QPainter *, int x, int y, int w, int h,
     101                        int tx, int ty, int paintPhase);
    114102    virtual void layout();
    115103    virtual void calcMinMaxWidth();
     
    118106    virtual short lineHeight(bool b) const;
    119107    virtual short baselinePosition(bool b) const;
    120    
     108
    121109    virtual void setCellWidths( );
    122 
    123     int cellPadding() { return m_cellPadding; }
    124     void setCellPadding(int cellPadding) { m_cellPadding = cellPadding; }
    125    
    126     int getBaseline(int row) {return rowInfo[row].baseline;}
    127110
    128111    virtual void position(int x, int y, int from, int len, int width, bool reverse, bool firstLine, int);
     
    133116    virtual int borderBottomExtra();
    134117
    135     void closeRow();
    136     void setNeedsCellsRecalc();
    137     void recalcCells();
    138 
    139118#ifndef NDEBUG
    140119    virtual void dump(QTextStream *stream, QString ind = "") const;
    141120#endif
    142 
    143 public:
    144     /*
    145      * For each table element with a different width a ColInfo struct is
    146      * maintained. Consider for example the following table:
    147      * +---+---+---+
    148      * | A | B | C |
    149      * +---+---+---+
    150      * |   D   | E |
    151      * +-------+---+
    152      *
    153      * This table would result in 4 ColInfo structs being allocated.
    154      * 1 for A, 1 for B, 1 for C & E, and 1 for D.
    155      *
    156      * Note that C and E share the same ColInfo.
    157      *
    158      * Note that D has a seperate ColInfo entry.
    159      *
    160      * There is always 1 default ColInfo entry which stretches across the
    161      * entire table.
    162      */
    163     struct ColInfo
    164     {
    165         ColInfo()
    166         {
    167             needsRecalc();
    168         }
    169 
    170         void needsRecalc() {
    171             span = start = min = max = value = 0;
    172             minCell = maxCell = widthCell = 0;
    173             type=khtml::Variable;
    174             needRecalc = true;
    175         }
    176            
    177         int     span;
    178         int     start;
    179         int     min;
    180         int     max;
    181         RenderTableCell* minCell;
    182         RenderTableCell* maxCell;
    183         khtml::LengthType       type;
    184         int     value;
    185         RenderTableCell* widthCell;
    186         bool    needRecalc;
     121    struct ColumnStruct {
     122        enum {
     123            WidthUndefined = 0xffff
     124        };
     125        ColumnStruct() {
     126            span = 1;
     127            width = WidthUndefined;
     128        }
     129        ushort span;
     130        ushort width; // the calculated position of the column
    187131    };
    188132
    189     struct RowInfo
    190     {
    191         int height;
    192         int percentage;
    193         int baseline;
    194     };
    195    
     133    QMemArray<int> columnPos;
     134    QMemArray<ColumnStruct> columns;
     135
     136    void splitColumn( int pos, int firstSpan );
     137    void appendColumn( int span );
     138    int numEffCols() const { return columns.size(); }
     139    int spanOfEffCol( int effCol ) const { return columns[effCol].span; }
     140    int colToEffCol( int col ) const {
     141        int c = 0;
     142        int i = 0;
     143        while ( c < col && i < (int)columns.size() ) {
     144            c += columns[i].span;
     145            i++;
     146        }
     147        return i;
     148    }
     149    int effColToCol( int effCol ) const {
     150        int c = 0;
     151        for ( int i = 0; i < effCol; i++ )
     152            c += columns[i].span;
     153        return c;
     154    }
     155
     156    int bordersAndSpacing() const {
     157        return borderLeft() + borderRight() + (numEffCols()+1) * cellSpacing();
     158    }
     159
     160    RenderTableCol *colElement( int col );
     161
     162    void setNeedSectionRecalc() { needSectionRecalc = true; }
     163
     164    virtual RenderObject* removeChildNode(RenderObject* child);
     165
    196166protected:
    197167
    198     void recalcColInfo( ColInfo *col );
    199 
    200     // This function calculates the actual widths of the columns
    201     void calcColWidth();
    202 
    203     // calculates the height of each row
    204     void calcRowHeight(int r);
    205 
    206     void layoutRows(int yoff);
    207 
    208     void setCells( unsigned int r, unsigned int c, RenderTableCell *cell );
    209     void addRows( int num );
    210     void addColumns( int num );
    211 
    212     RenderTableCell ***cells;
    213 
    214     class ColInfoLine : public QPtrVector<ColInfo>
    215     {
    216     public:
    217         ColInfoLine() : QPtrVector<ColInfo>()
    218         { setAutoDelete(true); }
    219         ColInfoLine(int i) : QPtrVector<ColInfo>(i)
    220         { setAutoDelete(true); }
    221         ColInfoLine(const QPtrVector<ColInfo> &v) : QPtrVector<ColInfo>(v)
    222         { setAutoDelete(true); }
    223     };
    224 
    225     QPtrVector<ColInfoLine> colInfos;
    226 
    227     void calcColMinMax();
    228     void calcSingleColMinMax(int c, ColInfo* col);
    229     void calcFinalColMax(int c, ColInfo* col);
    230     void spreadSpanMinMax(int col, int span, int min, int max, khtml::LengthType type);
    231     int distributeWidth(int distrib, khtml::LengthType type, int typeCols );
    232     int distributeMinWidth(int distrib, khtml::LengthType distType,
    233             khtml::LengthType toType, int start, int span, bool minlimit );
    234     int distributeMaxWidth(int distrib, LengthType distType,
    235             LengthType toType, int start, int span);
    236     int distributeRest(int distrib, khtml::LengthType type, int divider );
    237 
    238     int maxColSpan;
    239 
    240     QMemArray<RowInfo> rowInfo;
    241    
    242     QMemArray<int> columnPos;
    243     QMemArray<int> colMaxWidth;
    244     QMemArray<int> colMinWidth;
    245     QMemArray<khtml::LengthType> colType;
    246     QMemArray<int> colValue;
    247     QMemArray<int> actColWidth;
    248     unsigned int col;
    249     unsigned int totalCols;
    250     unsigned int row;
    251     unsigned int totalRows;
    252     unsigned int allocRows;
    253 
    254     unsigned int totalPercent ;
    255     unsigned int totalRelative ;
    256 
    257     RenderTableCaption *tCaption;
     168    void recalcSections();
     169
     170    friend class AutoTableLayout;
     171    friend class FixedTableLayout;
     172
     173    RenderFlow         *tCaption;
    258174    RenderTableSection *head;
    259175    RenderTableSection *foot;
    260176    RenderTableSection *firstBody;
    261177
    262     Frame frame;
    263     Rules rules;
    264 
    265     int m_cellPadding;
    266    
    267     RenderTableCol *_oldColElem;
    268     int _currentCol; // keeps track of current col for col/colgroup stuff
    269     int spacing;
    270     short _lastParentWidth      : 16;
    271     bool incremental            : 1;
    272     bool collapseBorders        : 1;
    273     bool colWidthKnown          : 1;
    274     bool needsCellsRecalc       : 1;
    275     bool hasPercent             : 1;
     178    TableLayout *tableLayout;
     179
     180    Frame frame                 : 4;
     181    Rules rules                 : 4;
     182
     183    bool has_col_elems          : 1;
     184    uint spacing                : 11;
     185    uint padding                : 11;
     186    uint needSectionRecalc      : 1;
    276187};
    277188
    278189// -------------------------------------------------------------------------
    279190
    280 class RenderTableSection : public RenderContainer
     191class RenderTableSection : public RenderBox
    281192{
    282193public:
    283194    RenderTableSection(DOM::NodeImpl* node);
    284195    ~RenderTableSection();
     196    virtual void detach(RenderArena* arena);
     197
     198    virtual void setStyle(RenderStyle *style);
    285199
    286200    virtual const char *renderName() const { return "RenderTableSection"; }
    287 
    288     int numRows() { return nrows; }
    289201
    290202    // overrides
     
    295207    virtual void position(int, int, int, int, int, bool, bool, int) {}
    296208
    297     virtual void setTable(RenderTable *t) { table = t; }
    298 
    299209#ifndef NDEBUG
    300210    virtual void dump(QTextStream *stream, QString ind = "") const;
    301211#endif
    302212
     213    void addCell( RenderTableCell *cell );
     214
     215    void setCellWidths();
     216    void calcRowHeight();
     217    int layoutRows( int height );
     218
     219    RenderTable *table() const { return static_cast<RenderTable *>(parent()); }
     220
     221    typedef QMemArray<RenderTableCell *> Row;
     222    struct RowStruct {
     223        Row *row;
     224        int baseLine;
     225        Length height;
     226    };
     227
     228    RenderTableCell *&cellAt( int row,  int col ) {
     229        return (*(grid[row].row))[col];
     230    }
     231    RenderTableCell *cellAt( int row,  int col ) const {
     232        return (*(grid[row].row))[col];
     233    }
     234
     235    virtual void paint( QPainter *, int x, int y, int w, int h,
     236                        int tx, int ty, int paintPhase);
     237
     238    int numRows() const { return grid.size(); }
     239    int getBaseline(int row) {return grid[row].baseLine;}
     240
     241    void setNeedCellRecalc() {
     242        needCellRecalc = true;
     243        table()->setNeedSectionRecalc();
     244    }
     245
     246    virtual RenderObject* removeChildNode(RenderObject* child);
     247
     248    // this gets a cell grid data structure. changing the number of
     249    // columns is done by the table
     250    QMemArray<RowStruct> grid;
     251    QMemArray<int> rowPos;
     252
     253    ushort cCol : 15;
     254    short cRow : 16;
     255    bool needCellRecalc : 1;
     256
     257    void recalcCells();
    303258protected:
    304     RenderTable *table;
    305     int nrows;
     259    void ensureRows( int numRows );
     260    void clearGrid();
    306261};
    307262
     
    312267public:
    313268    RenderTableRow(DOM::NodeImpl* node);
    314     ~RenderTableRow();
    315 
     269
     270    virtual void detach(RenderArena* arena);
     271
     272    virtual void setStyle( RenderStyle* );
    316273    virtual const char *renderName() const { return "RenderTableRow"; }
    317 
    318     long rowIndex() const;
    319     void setRowIndex( long );
    320 
    321     long sectionRowIndex() const { return rIndex; }
    322     void setSectionRowIndex( long i ) { rIndex = i; }
    323274
    324275    virtual bool isTableRow() const { return true; }
     
    326277    // overrides
    327278    virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
     279    virtual RenderObject* removeChildNode(RenderObject* child);
    328280
    329281    virtual short lineHeight( bool ) const { return 0; }
    330282    virtual void position(int, int, int, int, int, bool, bool, int) {}
    331283
    332     virtual void close();
    333 
    334     virtual void repaint(bool immediate=false);
    335 
    336284    virtual void layout();
    337285
    338     virtual void setTable(RenderTable *t) { table = t; }
     286    RenderTable *table() const { return static_cast<RenderTable *>(parent()->parent()); }
     287    RenderTableSection *section() const { return static_cast<RenderTableSection *>(parent()); }
    339288
    340289#ifndef NDEBUG
    341290    virtual void dump(QTextStream *stream, QString ind = "") const;
    342291#endif
    343 
    344 protected:
    345     RenderTable *table;
    346 
    347     // relative to the current section!
    348     int rIndex;
    349     int ncols;
    350292};
    351293
     
    356298public:
    357299    RenderTableCell(DOM::NodeImpl* node);
    358     ~RenderTableCell();
     300
     301    virtual void detach(RenderArena* arena);
    359302
    360303    virtual const char *renderName() const { return "RenderTableCell"; }
     
    365308    void setCellIndex( long ) { }
    366309
    367     long colSpan() const { return cSpan; }
    368     void setColSpan( long c ) { cSpan = c; }
    369 
    370     long rowSpan() const { return rSpan; }
    371     void setRowSpan( long r ) { rSpan = r; }
    372 
    373     bool noWrap() const { return nWrap; }
    374     void setNoWrap(bool nw) { nWrap = nw; }
     310    unsigned short colSpan() const { return cSpan; }
     311    void setColSpan( unsigned short c ) { cSpan = c; }
     312
     313    unsigned short rowSpan() const { return rSpan; }
     314    void setRowSpan( unsigned short r ) { rSpan = r; }
    375315
    376316    int col() const { return _col; }
     
    378318    int row() const { return _row; }
    379319    void setRow(int r) { _row = r; }
    380 
    381     khtml::LengthType colType();
    382320
    383321    // overrides
     
    386324    virtual void setWidth( int width );
    387325    virtual void setStyle( RenderStyle *style );
    388     virtual void repaint(bool immediate=false);
    389    
    390     virtual int paddingTop() const;
    391     virtual int paddingBottom() const;
    392     virtual int paddingLeft() const;
    393     virtual int paddingRight() const;
    394     virtual bool hasPadding() const {
    395         if (m_table && m_table->cellPadding() != -1)
    396             return true;
    397         return style()->hasPadding();
    398     }
    399    
     326
    400327    virtual void updateFromElement();
    401 
    402     void setRowHeight(int h) { rowHeight = h; }
    403    
    404     int getCellPercentageHeight() { return cellPercentageHeight; }
    405     void setCellPercentageHeight(int h) { cellPercentageHeight = h; }
    406    
    407     void setRowImpl(RenderTableRow *r) { rowimpl = r; }
    408328
    409329    void setCellTopExtra(int p) { _topExtra = p; }
    410330    void setCellBottomExtra(int p) { _bottomExtra = p; }
    411331
    412     virtual void setTable(RenderTable *t) { m_table = t; }
    413     RenderTable *table() const { return m_table; }
    414 
    415     virtual void paint(QPainter* p, int x, int y,
    416                        int w, int h, int tx, int ty, int paintPhase);
     332    int getCellPercentageHeight() const;
     333    void setCellPercentageHeight(int h);
     334   
     335    virtual void paint( QPainter* p, int x, int y,
     336                        int w, int h, int tx, int ty, int paintPhase);
    417337
    418338    virtual void close();
     
    428348    virtual int borderTopExtra() { return _topExtra; }
    429349    virtual int borderBottomExtra() { return _bottomExtra; }
     350
     351    RenderTable *table() const { return static_cast<RenderTable *>(parent()->parent()->parent()); }
     352    RenderTableSection *section() const { return static_cast<RenderTableSection *>(parent()->parent()); }
    430353
    431354#ifndef NDEBUG
     
    440363
    441364protected:
    442     RenderTable *m_table;
    443 
    444365    virtual void paintBoxDecorations(QPainter *p,int _x, int _y,
    445366                                     int _w, int _h, int _tx, int _ty);
    446 
     367   
    447368    short _row;
    448369    short _col;
    449     short rSpan;
    450     short cSpan;
    451     int _id;
    452     int rowHeight;
    453     int cellPercentageHeight;
    454     int _topExtra;
    455     int _bottomExtra;
     370    ushort rSpan;
     371    ushort cSpan;
     372    int _topExtra : 31;
    456373    bool nWrap : 1;
     374    int _bottomExtra : 31;
    457375    bool m_widthChanged : 1;
    458 
    459     RenderTableRow *rowimpl;
    460 };
     376   
     377    int m_percentageHeight;
     378};
     379
    461380
    462381// -------------------------------------------------------------------------
     
    466385public:
    467386    RenderTableCol(DOM::NodeImpl* node);
    468     ~RenderTableCol();
    469387
    470388    virtual const char *renderName() const { return "RenderTableCol"; }
    471 
    472     void setStartCol( int c ) {_startCol = _currentCol = c; }
    473     int col() { return _startCol; }
    474     int lastCol() { return _currentCol; }
    475389
    476390    long span() const { return _span; }
     
    478392
    479393    virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0);
     394
     395    virtual bool isTableCol() const { return true; }
    480396
    481397    virtual short lineHeight( bool ) const { return 0; }
     
    483399    virtual void layout() {}
    484400
    485     virtual void setTable(RenderTable *t) { table = t; }
    486 
    487401    virtual void updateFromElement();
    488402
     
    492406
    493407protected:
    494     RenderTable *table;
    495     int _span;
    496     int _currentCol;
    497     int _startCol;
    498 
    499     // could be ID_COL or ID_COLGROUP ... The DOM is not quite clear on
    500     // this, but since both elements work quite similar, we use one
    501     // DOMElement for them...
    502     ushort _id;
    503 };
    504 
    505 // -------------------------------------------------------------------------
    506 
    507 class RenderTableCaption : public RenderFlow
    508 {
    509 public:
    510     RenderTableCaption(DOM::NodeImpl*);
    511     ~RenderTableCaption();
    512 
    513     virtual const char *renderName() const { return "RenderTableCaption"; }
    514 
    515     virtual void setTable(RenderTable *t) { table = t; }
    516 protected:
    517     RenderTable *table;
    518 };
    519 
    520 };
    521 #endif
    522 
     408    short _span;
     409};
     410
     411};
     412#endif
     413
  • trunk/WebCore/khtml/xml/dom_docimpl.cpp

    r3328 r3351  
    764764    case ID_TBODY:
    765765    case ID_TFOOT:
    766         n = new HTMLTableSectionElementImpl(docPtr(), id);
     766        n = new HTMLTableSectionElementImpl(docPtr(), id, false);
    767767        break;
    768768
  • trunk/WebCore/khtml/xml/dom_nodeimpl.cpp

    r3098 r3351  
    6969      m_active( false ),
    7070      m_styleElement( false ),
     71      m_implicit( false ),
    7172      m_rendererNeedsClose( false )
    7273{
     
    901902    if (m_active) { *stream << " active"; }
    902903    if (m_styleElement) { *stream << " styleElement"; }
     904    if (m_implicit) { *stream << " implicit"; }
    903905
    904906    *stream << " tabIndex=" << m_tabIndex;
  • trunk/WebCore/khtml/xml/dom_nodeimpl.h

    r3098 r3351  
    187187    bool inDocument() const { return m_inDocument; }
    188188    bool styleElement() const { return m_styleElement; }
     189    bool implicitNode() const { return m_implicit; }
    189190    void setHasID(bool b=true) { m_hasId = b; }
    190191    void setHasClass(bool b=true) { m_hasClass = b; }
     
    396397    bool m_active : 1;
    397398    bool m_styleElement : 1; // contains stylesheet text
     399    bool m_implicit : 1; // implicitely generated by the parser
    398400    bool m_rendererNeedsClose : 1;
    399401
    400     // 2 bits unused
     402    // 1 bit unused
    401403};
    402404
Note: See TracChangeset for help on using the changeset viewer.