Changeset 3351 in webkit
- Timestamp:
- Jan 17, 2003, 2:42:07 PM (22 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 3 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog-2003-10-25
r3350 r3351 1 2003-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 1 175 2003-01-17 Darin Adler <darin@apple.com> 2 176 -
trunk/WebCore/ChangeLog-2005-08-23
r3350 r3351 1 2003-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 1 175 2003-01-17 Darin Adler <darin@apple.com> 2 176 -
trunk/WebCore/WebCore.pbproj/project.pbxproj
r3348 r3351 176 176 </plist> 177 177 "; 178 shouldUseHeadermap = 0; 178 179 }; 179 180 0867D69DFE84028FC02AAC07 = { … … 479 480 93F12CB303CCFD570000011C, 480 481 93F12CC803CD0AE60000011C, 482 BCF0192703D3802200B2D04D, 481 483 931BFCD003D4AEDA008635CE, 482 484 931BFCD403D4AEE5008635CE, … … 719 721 93F12CAE03CCFD570000011C, 720 722 93F12CB003CCFD570000011C, 723 BCF0192603D3802200B2D04D, 721 724 931BFCD103D4AEDA008635CE, 722 725 931BFCD503D4AEE5008635CE, … … 1453 1456 BC7294FE03804B5600A80166 = { 1454 1457 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; 1455 1482 isa = PBXBuildFile; 1456 1483 settings = { … … 4169 4196 F523D2C702DE4438018635CA, 4170 4197 F523D2C602DE4438018635CA, 4198 BC7294FB03804B5600A80166, 4199 BC7294FC03804B5600A80166, 4200 BCF0192403D3802200B2D04D, 4201 BCF0192503D3802200B2D04D, 4171 4202 ); 4172 4203 isa = PBXGroup; -
trunk/WebCore/khtml/css/cssparser.cpp
r3098 r3351 1199 1199 1200 1200 case CSS_PROP_UNICODE_BIDI: // normal | embed | bidi-override | inherit 1201 case CSS_PROP_WHITE_SPACE: // normal | pre | nowrap | inherit1201 case CSS_PROP_WHITE_SPACE: // normal | pre | nowrap | -konq-nowrap | inherit 1202 1202 case CSS_PROP_FONT_STRETCH: 1203 1203 // normal | wider | narrower | ultra-condensed | extra-condensed | condensed | -
trunk/WebCore/khtml/css/cssstyleselector.cpp
r3304 r3351 1744 1744 EWhiteSpace s; 1745 1745 switch(primitiveValue->getIdent()) { 1746 case CSS_VAL__KONQ_NOWRAP: 1747 s = KONQ_NOWRAP; 1748 break; 1746 1749 case CSS_VAL_NOWRAP: 1747 1750 s = NOWRAP; -
trunk/WebCore/khtml/css/cssvalues.c
r2831 r3351 109 109 enum 110 110 { 111 TOTAL_KEYWORDS = 18 0,111 TOTAL_KEYWORDS = 181, 112 112 MIN_WORD_LENGTH = 3, 113 113 MAX_WORD_LENGTH = 21, … … 281 281 {"higher", CSS_VAL_HIGHER}, 282 282 {"table-column", CSS_VAL_TABLE_COLUMN}, 283 {"-konq-nowrap", CSS_VAL__KONQ_NOWRAP}, 283 284 {"message-box", CSS_VAL_MESSAGE_BOX}, 284 285 {"ultra-condensed", CSS_VAL_ULTRA_CONDENSED}, … … 317 318 -1, -1, -1, -1, -1, 18, -1, -1, 318 319 -1, -1, -1, -1, -1, -1, -1, 19, 319 -30 2, -160, -2, 22, -1, -1, -1, -1,320 -303, -161, -2, 22, -1, -1, -1, -1, 320 321 -1, -1, 23, -1, -1, 24, -1, -1, 321 322 -1, -1, -1, -1, 25, -1, -1, 26, … … 393 394 -1, -1, -1, -1, -1, -1, -1, -1, 394 395 -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, 430 430 -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, 441 439 -1, -1, -1, -1, -1, -1, -1, -1, 442 440 -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 477 478 }; 478 479 … … 691 692 "thin", 692 693 "underline", 694 "-konq-nowrap", 693 695 "-konq-normal", 694 696 "-konq-around-floats", -
trunk/WebCore/khtml/css/cssvalues.h
r2831 r3351 188 188 #define CSS_VAL_THIN 177 189 189 #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 192 193 193 #define CSS_VAL_TOTAL 18 1194 #define CSS_VAL_TOTAL 182 194 195 #endif 195 196 -
trunk/WebCore/khtml/css/cssvalues.in
r1024 r3351 259 259 thin 260 260 underline 261 -konq-nowrap 261 262 # CSS_PROP__KONQ_FLOW_MODE 262 263 -konq-normal -
trunk/WebCore/khtml/css/html4.css
r3285 r3351 188 188 border-spacing: 2px; 189 189 border-color: gray; 190 padding: 1px; 191 -konq-flow-mode: -konq-around-floats; 190 -konq-flow-mode: -konq-around-floats; 192 191 } 193 192 … … 208 207 display: table-header-group; 209 208 vertical-align: middle; 210 border: inherit;209 border-color: inherit; 211 210 } 212 211 … … 214 213 display: table-row-group; 215 214 vertical-align: middle; 216 border : inherit;215 border-color: inherit; 217 216 } 218 217 … … 220 219 display: table-footer-group; 221 220 vertical-align: middle; 222 border: inherit; 221 border-color: inherit; 223 222 } 224 223 -
trunk/WebCore/khtml/dom/html_table.cpp
r1326 r3351 607 607 { 608 608 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; 610 614 } 611 615 612 616 void HTMLTableElement::deleteRow( long index ) 613 617 { 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); 616 623 } 617 624 … … 737 744 { 738 745 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; 740 751 } 741 752 742 753 void HTMLTableRowElement::deleteCell( long index ) 743 754 { 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); 746 760 } 747 761 … … 837 851 { 838 852 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; 840 858 } 841 859 842 860 void HTMLTableSectionElement::deleteRow( long index ) 843 861 { 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 43 43 44 44 #include <kdebug.h> 45 #include <kglobal.h> 45 46 46 47 using namespace khtml; … … 55 56 firstBody = 0; 56 57 58 #if 0 57 59 rules = None; 58 60 frame = Void; 59 60 m_cellPadding = -1;61 #endif 62 padding = 1; 61 63 62 incremental = false;63 64 m_noBorder = true; 64 65 m_solid = false; … … 72 73 { 73 74 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 }96 75 } 97 76 … … 136 115 replaceChild ( s, foot, exceptioncode ); 137 116 r = s; 138 } 139 else if( firstBody ) 117 } else if( firstBody ) 140 118 r = insertBefore( s, firstBody, exceptioncode ); 141 119 else … … 150 128 NodeImpl* r; 151 129 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 158 134 r = appendChild( s, exceptioncode ); 135 firstBody = s; 159 136 160 137 return r; … … 166 143 { 167 144 int exceptioncode = 0; 168 head = new HTMLTableSectionElementImpl(docPtr(), ID_THEAD );145 head = new HTMLTableSectionElementImpl(docPtr(), ID_THEAD, true /* implicit */); 169 146 if(foot) 170 147 insertBefore( head, foot, exceptioncode ); 171 if(firstBody)148 else if(firstBody) 172 149 insertBefore( head, firstBody, exceptioncode); 173 150 else … … 191 168 { 192 169 int exceptioncode = 0; 193 foot = new HTMLTableSectionElementImpl(docPtr(), ID_TFOOT );170 foot = new HTMLTableSectionElementImpl(docPtr(), ID_TFOOT, true /*implicit */); 194 171 if(firstBody) 195 172 insertBefore( foot, firstBody, exceptioncode ); … … 229 206 } 230 207 231 HTMLElementImpl *HTMLTableElementImpl::insertRow( long index ) 232 { 208 HTMLElementImpl *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; 233 218 // IE treats index=-1 as default value meaning 'append after last' 234 219 // This isn't in the DOM. So, not implemented yet. 235 220 HTMLTableSectionElementImpl* section = 0L; 221 HTMLTableSectionElementImpl* lastSection = 0L; 236 222 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) ) 240 230 { 241 231 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 266 void HTMLTableElementImpl::deleteRow( long index, int &exceptioncode ) 256 267 { 257 268 HTMLTableSectionElementImpl* section = 0L; 258 269 NodeImpl *node = firstChild(); 270 bool lastRow = index == -1; 271 HTMLTableSectionElementImpl* lastSection = 0L; 272 bool found = false; 259 273 for ( ; node ; node = node->nextSibling() ) 260 274 { 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) ) 262 276 { 263 277 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; 273 300 } 274 301 … … 279 306 #endif 280 307 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) { 309 309 // First add the child. 310 310 HTMLElementImpl::addChild(child); … … 313 313 return this; 314 314 } 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; 316 342 } 317 343 … … 323 349 case ATTR_WIDTH: 324 350 if (!attr->value().isEmpty()) 325 addCSSLength( CSS_PROP_WIDTH, attr->value());351 addCSSLength( CSS_PROP_WIDTH, attr->value() ); 326 352 else 327 353 removeCSSProperty(CSS_PROP_WIDTH); … … 430 456 case ATTR_CELLPADDING: 431 457 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; 439 461 break; 440 462 case ATTR_COLS: … … 467 489 } 468 490 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 } 491 void 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 ); 480 516 } 481 517 … … 511 547 addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID); 512 548 addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID); 513 m_solid = true;514 549 } 515 550 break; … … 531 566 break; 532 567 } 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; 533 574 case ATTR_NOSAVE: 534 575 break; … … 541 582 542 583 HTMLTableSectionElementImpl::HTMLTableSectionElementImpl(DocumentPtr *doc, 543 ushort tagid )584 ushort tagid, bool implicit) 544 585 : HTMLTablePartElementImpl(doc) 545 586 { 546 587 _id = tagid; 588 m_implicit = implicit; 547 589 } 548 590 549 591 HTMLTableSectionElementImpl::~HTMLTableSectionElementImpl() 550 592 { 551 nrows = 0;552 593 } 553 594 … … 575 616 // these functions are rather slow, since we need to get the row at 576 617 // 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 618 HTMLElementImpl *HTMLTableSectionElementImpl::insertRow( long index, int& exceptioncode ) 619 { 620 HTMLTableRowElementImpl *r = 0L; 583 621 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; 596 642 return r; 597 643 } 598 644 599 void HTMLTableSectionElementImpl::deleteRow( long index ) 600 { 601 if(index < 0) return; 645 void HTMLTableSectionElementImpl::deleteRow( long index, int &exceptioncode ) 646 { 602 647 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 ) 607 651 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 658 int 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; 610 669 } 611 670 612 671 // ------------------------------------------------------------------------- 613 614 HTMLTableRowElementImpl::HTMLTableRowElementImpl(DocumentPtr *doc)615 : HTMLTablePartElementImpl(doc)616 {617 }618 619 HTMLTableRowElementImpl::~HTMLTableRowElementImpl()620 {621 }622 672 623 673 NodeImpl::Id HTMLTableRowElementImpl::id() const … … 644 694 long HTMLTableRowElementImpl::rowIndex() const 645 695 { 646 // some complex traversal stuff here to take into account that some rows may be in different sections647 696 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; 666 729 } 667 730 … … 680 743 } 681 744 682 HTMLElementImpl *HTMLTableRowElementImpl::insertCell( long index ) 683 { 684 HTMLTableCellElementImpl *c = new HTMLTableCellElementImpl(docPtr(), ID_TD); 685 745 HTMLElementImpl *HTMLTableRowElementImpl::insertCell( long index, int &exceptioncode ) 746 { 747 HTMLTableCellElementImpl *c = 0L; 686 748 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; 699 767 return c; 700 768 } 701 769 702 void HTMLTableRowElementImpl::deleteCell( long index ) 703 { 704 if(index < 0) return; 770 void HTMLTableRowElementImpl::deleteCell( long index, int &exceptioncode ) 771 { 705 772 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 ) 708 776 HTMLElementImpl::removeChild(children->item(index), exceptioncode); 709 } 710 if(children) delete children; 777 else 778 exceptioncode = DOMException::INDEX_SIZE_ERR; 779 delete children; 711 780 } 712 781 … … 719 788 _row = -1; 720 789 cSpan = rSpan = 1; 721 m_nowrap = false;722 790 _id = tag; 723 791 rowHeight = 0; 792 m_solid = false; 724 793 } 725 794 … … 749 818 break; 750 819 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); 752 824 break; 753 825 case ATTR_WIDTH: 754 826 if (!attr->value().isEmpty()) 755 addCSSLength( CSS_PROP_WIDTH, attr->value());827 addCSSLength( CSS_PROP_WIDTH, attr->value() ); 756 828 else 757 829 removeCSSProperty(CSS_PROP_WIDTH); 758 break;759 case ATTR_HEIGHT:760 if (!attr->value().isEmpty())761 addCSSLength(CSS_PROP_HEIGHT, attr->value());762 else763 removeCSSProperty(CSS_PROP_HEIGHT);764 830 break; 765 831 case ATTR_NOSAVE: … … 770 836 } 771 837 772 void HTMLTableCellElementImpl::init() 773 { 774 HTMLTablePartElementImpl::init(); 775 838 void HTMLTableCellElementImpl::attach() 839 { 776 840 HTMLElementImpl* p = static_cast<HTMLElementImpl*>(parentNode()); 777 841 while(p && p->id() != ID_TABLE) … … 795 859 } 796 860 } 861 862 HTMLTablePartElementImpl::attach(); 797 863 } 798 864 … … 800 866 801 867 HTMLTableColElementImpl::HTMLTableColElementImpl(DocumentPtr *doc, ushort i) 802 : HTML ElementImpl(doc)868 : HTMLTablePartElementImpl(doc) 803 869 { 804 870 _id = i; … … 806 872 } 807 873 808 HTMLTableColElementImpl::~HTMLTableColElementImpl()809 {810 }811 812 874 NodeImpl::Id HTMLTableColElementImpl::id() const 813 875 { … … 815 877 } 816 878 817 818 NodeImpl *HTMLTableColElementImpl::addChild(NodeImpl *child)819 {820 #ifdef DEBUG_LAYOUT821 kdDebug( 6030 ) << nodeName().string() << "(Table)::addChild( " << child->nodeName().string() << " )" << endl;822 #endif823 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 }840 879 841 880 void HTMLTableColElementImpl::parseAttribute(AttributeImpl *attr) … … 859 898 break; 860 899 default: 861 HTML ElementImpl::parseAttribute(attr);900 HTMLTablePartElementImpl::parseAttribute(attr); 862 901 } 863 902 … … 865 904 866 905 // ------------------------------------------------------------------------- 867 868 HTMLTableCaptionElementImpl::HTMLTableCaptionElementImpl(DocumentPtr *doc)869 : HTMLTablePartElementImpl(doc)870 {871 }872 873 HTMLTableCaptionElementImpl::~HTMLTableCaptionElementImpl()874 {875 }876 906 877 907 NodeImpl::Id HTMLTableCaptionElementImpl::id() const -
trunk/WebCore/khtml/html/html_tableimpl.h
r3098 r3351 75 75 virtual Id id() const; 76 76 77 virtual void attach();78 79 77 HTMLTableCaptionElementImpl *caption() const { return tCaption; } 80 78 NodeImpl *setCaption( HTMLTableCaptionElementImpl * ); … … 94 92 HTMLElementImpl *createCaption ( ); 95 93 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 ); 98 96 99 97 // overrides 100 98 virtual NodeImpl *addChild(NodeImpl *child); 101 99 virtual void parseAttribute(AttributeImpl *attr); 102 103 virtual void init(); 104 105 int cellPadding() { return m_cellPadding; } 106 100 virtual void attach(); 101 107 102 protected: 108 103 HTMLTableSectionElementImpl *head; … … 111 106 HTMLTableCaptionElementImpl *tCaption; 112 107 108 #if 0 113 109 Frame frame; 114 110 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; 121 117 friend class HTMLTableCellElementImpl; 122 118 }; … … 129 125 public: 130 126 HTMLTablePartElementImpl(DocumentPtr *doc) 131 : HTMLElementImpl(doc) , m_solid(false)127 : HTMLElementImpl(doc) 132 128 { } 133 129 134 130 virtual void parseAttribute(AttributeImpl *attr); 135 136 protected:137 bool m_solid : 1;138 131 }; 139 132 … … 143 136 { 144 137 public: 145 HTMLTableSectionElementImpl(DocumentPtr *doc, ushort tagid );138 HTMLTableSectionElementImpl(DocumentPtr *doc, ushort tagid, bool implicit); 146 139 147 140 ~HTMLTableSectionElementImpl(); … … 151 144 virtual NodeImpl *addChild(NodeImpl *child); 152 145 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; 157 150 158 151 protected: 159 152 ushort _id; 160 int nrows;161 153 }; 162 154 … … 166 158 { 167 159 public: 168 HTMLTableRowElementImpl(DocumentPtr *doc); 169 170 ~HTMLTableRowElementImpl(); 160 HTMLTableRowElementImpl(DocumentPtr *doc) 161 : HTMLTablePartElementImpl(doc) {} 171 162 172 163 virtual Id id() const; … … 177 168 long sectionRowIndex() const; 178 169 179 HTMLElementImpl *insertCell ( long index );180 void deleteCell ( long index );170 HTMLElementImpl *insertCell ( long index, int &exceptioncode ); 171 void deleteCell ( long index, int &exceptioncode ); 181 172 182 173 protected: … … 199 190 int row() const { return _row; } 200 191 void setRow(int r) { _row = r; } 201 192 202 193 int colSpan() const { return cSpan; } 203 194 int rowSpan() const { return rSpan; } 204 bool noWrap() const { return m_nowrap; } 205 195 206 196 virtual Id id() const { return _id; } 207 197 virtual void parseAttribute(AttributeImpl *attr); 208 virtual void init();198 virtual void attach(); 209 199 210 200 protected: … … 215 205 int _id; 216 206 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 212 class HTMLTableColElementImpl : public HTMLTablePartElementImpl 224 213 { 225 214 public: 226 215 HTMLTableColElementImpl(DocumentPtr *doc, ushort i); 227 216 228 ~HTMLTableColElementImpl();229 230 217 virtual Id id() const; 231 218 232 219 void setTable(HTMLTableElementImpl *t) { table = t; } 233 220 234 virtual NodeImpl *addChild(NodeImpl *child);235 236 221 // overrides 237 222 virtual void parseAttribute(AttributeImpl *attr); 238 223 239 224 int span() const { return _span; } 240 225 … … 253 238 { 254 239 public: 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; 261 244 virtual void parseAttribute(AttributeImpl *attr); 262 245 }; -
trunk/WebCore/khtml/html/htmlparser.cpp
r3304 r3351 668 668 e = new HTMLTableCellElementImpl(document, ID_TD); 669 669 else if ( current->id() == ID_TABLE ) 670 e = new HTMLTableSectionElementImpl( document, ID_TBODY );670 e = new HTMLTableSectionElementImpl( document, ID_TBODY, true /* implicit */ ); 671 671 else 672 672 e = new HTMLTableRowElementImpl( document ); … … 1038 1038 popBlock( ID_TBODY ); 1039 1039 popBlock( ID_TFOOT ); 1040 n = new HTMLTableSectionElementImpl(document, t->id );1040 n = new HTMLTableSectionElementImpl(document, t->id, false); 1041 1041 break; 1042 1042 -
trunk/WebCore/khtml/rendering/bidi.cpp
r3319 r3351 1033 1033 m_height = style()->borderTopWidth(); 1034 1034 1035 if(hasPadding()) 1036 { 1037 m_height += paddingTop(); 1038 toAdd += paddingBottom(); 1039 } 1035 m_height += paddingTop(); 1036 toAdd += paddingBottom(); 1040 1037 1041 1038 if(firstChild()) { -
trunk/WebCore/khtml/rendering/render_body.cpp
r3098 r3351 27 27 #include "khtmlview.h" 28 28 29 29 #include <kglobal.h> 30 30 #include <kdebug.h> 31 31 … … 103 103 #endif /* APPLE_CHANGES not defined */ 104 104 } 105 106 int 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 43 43 virtual void repaint(bool immediate=false); 44 44 45 46 45 virtual void layout(); 47 48 46 virtual void setStyle(RenderStyle* style); 49 47 48 virtual int availableHeight() const; 49 50 50 protected: 51 51 virtual void paintBoxDecorations(QPainter *p,int _x, int _y, -
trunk/WebCore/khtml/rendering/render_box.cpp
r3280 r3351 108 108 { 109 109 short w = m_width - borderLeft() - borderRight(); 110 if (hasPadding()) 111 w -= paddingLeft() + paddingRight(); 110 w -= paddingLeft() + paddingRight(); 112 111 113 112 //kdDebug( 6040 ) << "RenderBox::contentWidth(2) = " << w << endl; … … 118 117 { 119 118 int h = m_height - borderTop() - borderBottom(); 120 if (hasPadding()) 121 h -= paddingTop() + paddingBottom(); 119 h -= paddingTop() + paddingBottom(); 122 120 123 121 return h; … … 716 714 } 717 715 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 } 716 short RenderBox::calcReplacedWidth() const 717 { 718 Length w = style()->width(); 719 720 switch( w.type ) { 721 case Fixed: 722 return w.value; 736 723 case Percent: 737 724 { 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 745 733 if (isFormElement()) 746 width-= (marginLeft() + marginRight());734 result -= (marginLeft() + marginRight()); 747 735 #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 745 int 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; 752 760 } 753 761 case Fixed: 754 width = w.value; 755 break; 762 return h.value; 756 763 default: 757 width = intrinsicWidth(); 758 break; 764 return intrinsicHeight(); 759 765 }; 760 761 return width; 762 } 763 764 int RenderBox::calcReplacedHeight() const 766 } 767 768 int RenderBox::availableHeight() const 765 769 { 766 770 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(); 820 790 } 821 791 … … 1016 986 ch = hl.value + cb->paddingTop() 1017 987 + cb->paddingBottom(); 988 else if (cb->isHtml()) 989 ch = cb->availableHeight(); 1018 990 else 1019 991 ch = cb->height(); … … 1023 995 if(!style()->bottom().isVariable()) 1024 996 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()) 1026 1002 { 1027 1003 h = style()->height().width(ch); -
trunk/WebCore/khtml/rendering/render_box.h
r3098 r3351 102 102 int calcWidthUsing(WidthType widthType, int cw, LengthType& lengthType); 103 103 104 virtual short calcReplacedWidth( bool* ieHack=0) const;104 virtual short calcReplacedWidth() const; 105 105 virtual int calcReplacedHeight() const; 106 106 107 virtual int availableHeight() const; 108 107 109 void calcVerticalMargins(); 108 110 -
trunk/WebCore/khtml/rendering/render_flow.cpp
r3304 r3351 417 417 m_height = 0; 418 418 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 432 423 int minHeight = m_height + toAdd; 433 424 m_overflowHeight = m_height; … … 1004 995 int left = 0; 1005 996 1006 if (style()->hasBorder()) 1007 left += borderLeft(); 1008 if (hasPadding()) 1009 left += paddingLeft(); 997 left += borderLeft() + paddingLeft(); 1010 998 1011 999 if ( firstLine && style()->direction() == LTR ) { … … 1048 1036 int right = m_width; 1049 1037 1050 if (style()->hasBorder()) 1051 right -= borderRight(); 1052 if (hasPadding()) 1053 right -= paddingRight(); 1038 right -= borderRight() + paddingRight(); 1054 1039 1055 1040 if ( firstLine && style()->direction() == RTL ) { … … 1301 1286 kdDebug( 6040 ) << (void *)this << ": adding overhanging floats xoff=" << xoff << " offset=" << offset << " child=" << child << endl; 1302 1287 #endif 1303 if ( !flow->specialObjects )1288 if ( !flow->specialObjects || (child && flow->layer()) ) 1304 1289 return; 1305 1290 … … 1317 1302 ( child && flow->yPos() + r->endY > height() ) ) ) { 1318 1303 1319 if ( child)1304 if (child) 1320 1305 r->noPaint = true; 1321 1306 … … 1620 1605 void RenderFlow::calcBlockMinMaxWidth() 1621 1606 { 1607 bool nowrap = style()->whiteSpace() == NOWRAP; 1608 1622 1609 RenderObject *child = firstChild(); 1623 1610 while(child != 0) … … 1671 1658 int w = child->minWidth() + margin; 1672 1659 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 1673 1664 w = child->maxWidth() + margin; 1674 1665 if(m_maxWidth < w) m_maxWidth = w; … … 1694 1685 } 1695 1686 1687 bool preOrNowrap = style()->whiteSpace() != NORMAL; 1696 1688 if (childrenInline()) 1697 1689 calcInlineMinMaxWidth(); … … 1701 1693 if(m_maxWidth < m_minWidth) m_maxWidth = m_minWidth; 1702 1694 1703 if (style()->width().isFixed()) 1695 if (preOrNowrap && childrenInline()) 1696 m_minWidth = m_maxWidth; 1697 1698 if (style()->width().isFixed() && style()->width().value > 0) 1704 1699 m_maxWidth = KMAX(m_minWidth,short(style()->width().value)); 1705 1706 if ( style()->whiteSpace() != NORMAL ) 1707 m_minWidth = m_maxWidth; 1708 1700 1709 1701 int toAdd = 0; 1710 if(style()->hasBorder()) 1711 toAdd = borderLeft() + borderRight(); 1712 if (hasPadding()) 1713 toAdd += paddingLeft() + paddingRight(); 1702 toAdd = borderLeft() + borderRight() + paddingLeft() + paddingRight(); 1714 1703 1715 1704 m_minWidth += toAdd; -
trunk/WebCore/khtml/rendering/render_form.cpp
r3148 r3351 75 75 return RenderWidget::baselinePosition( f ) - 2 - style()->fontMetrics().descent(); 76 76 #endif 77 }78 79 short RenderFormElement::calcReplacedWidth(bool*) const80 {81 Length w = style()->width();82 if ( w.isVariable() )83 return intrinsicWidth();84 else85 return RenderReplaced::calcReplacedWidth();86 }87 88 int RenderFormElement::calcReplacedHeight() const89 {90 Length h = style()->height();91 if ( h.isVariable() )92 return intrinsicHeight();93 else94 return RenderReplaced::calcReplacedHeight();95 77 } 96 78 -
trunk/WebCore/khtml/rendering/render_form.h
r3098 r3351 86 86 #endif 87 87 88 // IE does not scale according to intrinsicWidth/Height89 // aspect ratio :-(90 virtual short calcReplacedWidth(bool* ieHack=0) const;91 virtual int calcReplacedHeight() const;92 88 virtual void updateFromElement(); 93 89 -
trunk/WebCore/khtml/rendering/render_frames.cpp
r3238 r3351 914 914 } 915 915 916 // duplication of RenderFormElement... FIX THIS!917 short RenderPartObject::calcReplacedWidth(bool* ieHack) const918 {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.html939 // I am commenting this out, since it causes all plugins to have a min width of 0940 // all the time (unless they have a variable length). This is clearly wrong. - dwh941 if ( w.isVariable() ) {942 if (ieHack) // Move it inside. Only applies in the override case. -dwh943 *ieHack = true;944 return intrinsicWidth();945 }946 else947 return RenderReplaced::calcReplacedWidth();948 }949 950 int RenderPartObject::calcReplacedHeight() const951 {952 Length h = style()->height();953 if ( h.isVariable() )954 return intrinsicHeight();955 else956 return RenderReplaced::calcReplacedHeight();957 }958 // end duplication959 960 916 void RenderPartObject::layout( ) 961 917 { -
trunk/WebCore/khtml/rendering/render_frames.h
r2937 r3351 147 147 virtual void updateWidget(); 148 148 149 // IE does not scale according to intrinsicWidth/Height150 // aspect ratio :-(151 virtual short calcReplacedWidth(bool* ieHack=0) const;152 virtual int calcReplacedHeight() const;153 154 149 virtual bool partLoadingErrorNotify( khtml::ChildFrame *childFrame, const KURL& url, const QString& serviceType ); 155 150 -
trunk/WebCore/khtml/rendering/render_object.cpp
r3160 r3351 109 109 break; 110 110 case TABLE_CAPTION: 111 o = new (arena) Render TableCaption(node);111 o = new (arena) RenderFlow(node); 112 112 break; 113 113 } … … 869 869 int RenderObject::paddingTop() const 870 870 { 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; 875 879 } 876 880 877 881 int RenderObject::paddingBottom() const 878 882 { 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; 883 891 } 884 892 885 893 int RenderObject::paddingLeft() const 886 894 { 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; 891 903 } 892 904 893 905 int RenderObject::paddingRight() const 894 906 { 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; 899 915 } 900 916 -
trunk/WebCore/khtml/rendering/render_object.h
r3160 r3351 174 174 virtual bool isTableRow() const { return false; } 175 175 virtual bool isTableSection() const { return false; } 176 virtual bool isTableCol() const { return false; } 176 177 virtual bool isTable() const { return false; } 177 178 virtual bool isWidget() const { return false; } … … 309 310 virtual void close() { } 310 311 312 virtual int availableHeight() const { return 0; } 313 311 314 // does a query on the rendertree and finds the innernode 312 315 // and overURL for the given position … … 447 450 virtual int paddingLeft() const; 448 451 virtual int paddingRight() const; 449 virtual bool hasPadding() const { return style()->hasPadding(); }450 452 451 453 virtual int borderTop() const { return style()->borderTopWidth(); } -
trunk/WebCore/khtml/rendering/render_replaced.cpp
r3148 r3351 83 83 #endif 84 84 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() ) { 95 91 m_minWidth = 0; 96 m_maxWidth = width + toAdd;92 m_maxWidth = width; 97 93 } 98 94 else 99 m_minWidth = m_maxWidth = width + toAdd;95 m_minWidth = m_maxWidth = width; 100 96 101 97 setMinMaxKnown(); -
trunk/WebCore/khtml/rendering/render_root.cpp
r3098 r3351 51 51 m_maxWidth = m_minWidth; 52 52 53 m_rootWidth =0;54 m_ rootHeight=0;55 53 m_rootWidth = m_rootHeight = 0; 54 m_viewportWidth = m_viewportHeight = 0; 55 56 56 setPositioned(true); // to 0,0 :) 57 57 … … 123 123 void RenderRoot::layout() 124 124 { 125 //kdDebug(6040) << "RenderRoot::layout()" << endl;126 125 if (m_printingMode) 127 126 m_minWidth = m_width; 128 127 129 if(firstChild()) {128 if(firstChild()) 130 129 firstChild()->setLayouted(false); 131 }132 130 133 131 #ifdef SPEED_DEBUG … … 139 137 #ifdef SPEED_DEBUG 140 138 kdDebug() << "RenderRoot::calcMinMax time used=" << qt.elapsed() << endl; 141 // this fixes frameset resizing142 139 qt.start(); 143 140 #endif 144 141 145 RenderFlow::layout();146 142 #ifdef SPEED_DEBUG 147 143 kdDebug() << "RenderRoot::layout time used=" << qt.elapsed() << endl; 148 144 qt.start(); 149 145 #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; 160 152 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 164 164 // ### we could maybe do the call below better and only pass true if the docsize changed. 165 165 layoutSpecialObjects( true ); 166 166 167 #ifdef SPEED_DEBUG 167 168 kdDebug() << "RenderRoot::end time used=" << qt.elapsed() << endl; … … 170 171 layer()->setHeight(m_height); 171 172 layer()->setWidth(m_width); 172 173 173 174 setLayouted(); 174 //kdDebug(0) << "root: height = " << m_height << endl;175 175 } 176 176 … … 212 212 } 213 213 214 #ifdef BOX_DEBUG215 214 if (m_view) 216 215 { … … 218 217 _ty += m_view->contentsY(); 219 218 } 219 220 // 3. paint floats. 221 if (paintPhase == FLOAT_PHASE) 222 paintFloats(p, _x, _y, _w, _h, _tx, _ty); 223 224 #ifdef BOX_DEBUG 220 225 outlineBox(p, _tx, _ty); 221 226 #endif -
trunk/WebCore/khtml/rendering/render_root.h
r2752 r3351 75 75 virtual void setHeight( int height ) { m_rootHeight = m_height = height; } 76 76 77 int viewportWidth() const { return m_viewportWidth; } 78 int viewportHeight() const { return m_viewportHeight; } 79 77 80 protected: 78 81 … … 91 94 int m_rootHeight; 92 95 96 int m_viewportWidth; 97 int m_viewportHeight; 98 93 99 // used to ignore viewport width when printing to the printer 94 100 bool m_printingMode; -
trunk/WebCore/khtml/rendering/render_style.cpp
r3098 r3351 32 32 33 33 StyleSurroundData::StyleSurroundData() 34 : margin( Fixed ), padding( Fixed)34 : margin( Fixed ), padding( Variable ) 35 35 { 36 36 } -
trunk/WebCore/khtml/rendering/render_style.h
r3098 r3351 384 384 385 385 enum EWhiteSpace { 386 NORMAL, PRE, NOWRAP 386 NORMAL, PRE, NOWRAP, KONQ_NOWRAP 387 387 }; 388 388 … … 642 642 bool isFloating() const { return !(noninherited_flags._floating == FNONE); } 643 643 bool hasMargin() const { return surround->margin.nonZero(); } 644 bool hasPadding() const { return surround->padding.nonZero(); }645 644 bool hasBorder() const { return surround->border.hasBorder(); } 646 645 bool hasOffset() const { return surround->offset.nonZero(); } … … 706 705 707 706 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; } 709 708 710 709 short colSpan() const { return visual->colspan; } -
trunk/WebCore/khtml/rendering/render_table.cpp
r3286 r3351 7 7 * (C) 1999 Lars Knoll (knoll@kde.org) 8 8 * (C) 1999 Antti Koivisto (koivisto@kde.org) 9 * Copyright (C) 2002 Apple Computer, Inc.10 9 * 11 10 * This library is free software; you can redistribute it and/or … … 29 28 //#define DEBUG_LAYOUT 30 29 //#define BOX_DEBUG 31 32 30 #include "rendering/render_table.h" 31 #include "rendering/table_layout.h" 33 32 #include "html/html_tableimpl.h" 34 33 #include "misc/htmltags.h" 35 #include "xml/dom_docimpl.h"36 34 37 35 #include <kglobal.h> … … 45 43 using namespace khtml; 46 44 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 65 45 RenderTable::RenderTable(DOM::NodeImpl* node) 66 46 : RenderFlow(node) … … 68 48 69 49 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; 78 52 79 53 rules = None; 80 54 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; 94 60 95 61 columnPos.resize( 2 ); 96 colMaxWidth.resize( 1 );97 colMinWidth.resize( 1 );98 colValue.resize(1);99 colType.resize(1);100 actColWidth.resize(1);101 62 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 69 RenderTable::~RenderTable() 70 { 71 delete tableLayout; 72 } 73 74 void 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(); 108 86 columnPos[0] = spacing; 109 87 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 101 void 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(); 134 106 } 135 107 … … 152 124 } 153 125 154 void RenderTable::setStyle(RenderStyle *_style)155 {156 RenderFlow::setStyle(_style);157 158 // init RenderObject attributes159 // In quirks mode, we will accept display: inline and block as valid160 // display types for a table object (see www.sundancecatalog.com).161 // A table therefore should go ahead and check if it's inline as well162 // 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 only175 m_x = x + marginLeft();176 m_y = y + marginTop();177 }178 179 126 void RenderTable::addChild(RenderObject *child, RenderObject *beforeChild) 180 127 { … … 183 130 (beforeChild ? beforeChild->renderName() : "0") << " )" << endl; 184 131 #endif 132 RenderObject *o = child; 133 185 134 if (child->element() && child->element()->id() == ID_FORM) { 186 135 RenderContainer::addChild(child,beforeChild); 187 136 return; 188 137 } 189 190 RenderObject *o = child; 191 138 192 139 switch(child->style()->display()) 193 140 { 194 141 case TABLE_CAPTION: 195 tCaption = static_cast<Render TableCaption*>(child);142 tCaption = static_cast<RenderFlow *>(child); 196 143 break; 197 144 case TABLE_COLUMN: 198 145 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; 218 148 return; 219 149 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); 222 154 break; 223 155 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 227 161 case TABLE_ROW_GROUP: 228 if(incremental && !columnPos[totalCols]);// calcColWidth();229 162 if(!firstBody) 230 163 firstBody = static_cast<RenderTableSection *>(child); 231 164 break; 232 165 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 { 238 170 RenderObject *lastBox = beforeChild; 239 171 while ( lastBox && lastBox->parent()->isAnonymousBox() && … … 244 176 return; 245 177 } 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; 247 181 o = new (renderArena()) RenderTableSection(0 /* anonymous */); 248 182 RenderStyle *newStyle = new RenderStyle(); 249 183 newStyle->inheritFrom(style()); 250 184 newStyle->setDisplay(TABLE_ROW_GROUP); 251 185 o->setStyle(newStyle); 252 186 o->setIsAnonymousBox(true); … … 260 194 } 261 195 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 200 void 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 233 void 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 421 262 RenderObject *child = firstChild(); 422 263 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 ); 436 269 } 437 270 child = child->nextSibling(); 438 271 } 439 272 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); 1410 276 m_height += tCaption->height() + tCaption->marginTop() + tCaption->marginBottom(); 1411 277 } 1412 278 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(); 1458 280 1459 281 // html tables with percent height are relative to view … … 1488 310 } 1489 311 } 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 ); 1531 322 } 1532 323 } 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 } 1630 365 1631 366 void RenderTable::setCellWidths() … … 1635 370 #endif 1636 371 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 380 void 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 1663 386 _tx += xPos(); 1664 387 _ty += yPos(); … … 1674 397 1675 398 #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(); 1734 410 } 1735 411 … … 1743 419 KHTMLAssert( !minMaxKnown() ); 1744 420 1745 if ( needsCellsRecalc ) 1746 recalcCells(); 421 if ( needSectionRecalc ) 422 recalcSections(); 423 1747 424 #ifdef DEBUG_LAYOUT 1748 425 kdDebug( 6040 ) << renderName() << "(Table " << this << ")::calcMinMaxWidth()" << endl; 1749 426 #endif 1750 427 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(); 1757 432 1758 433 setMinMaxKnown(); 1759 434 #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; 1761 436 #endif 1762 437 } … … 1786 461 } 1787 462 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 464 void 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++; 1862 492 } 1863 493 } 1864 } 1865 1866 recalcColInfos(); 1867 } 494 child = child->nextSibling(); 495 } 496 columnPos.resize( numEffCols()+1 ); 497 setMinMaxKnown( false ); 498 setLayouted( false ); 499 } 500 501 void 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 532 RenderTableCol *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 559 void 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 615 RenderObject* RenderTable::removeChildNode(RenderObject* child) 616 { 617 setNeedSectionRecalc(); 618 return RenderContainer::removeChildNode( child ); 619 } 620 1868 621 1869 622 #ifndef NDEBUG 1870 623 void RenderTable::dump(QTextStream *stream, QString ind) const 1871 624 { 1872 *stream << " totalCols=" << totalCols;1873 *stream << " totalRows=" << totalRows;1874 1875 625 if (tCaption) 1876 626 *stream << " tCaption"; … … 1880 630 *stream << " foot"; 1881 631 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; 1890 636 1891 637 RenderFlow::dump(stream,ind); … … 1896 642 1897 643 RenderTableSection::RenderTableSection(DOM::NodeImpl* node) 1898 : Render Container(node)644 : RenderBox(node) 1899 645 { 1900 646 // init RenderObject attributes 1901 647 setInline(false); // our object is not Inline 1902 nrows = 0; 648 cCol = 0; 649 cRow = -1; 650 needCellRecalc = false; 1903 651 } 1904 652 1905 653 RenderTableSection::~RenderTableSection() 654 { 655 clearGrid(); 656 } 657 658 void RenderTableSection::detach(RenderArena* arena) 1906 659 { 1907 660 // recalc cell info because RenderTable has unguarded pointers 1908 661 // 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 668 void 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); 1911 677 } 1912 678 … … 1925 691 1926 692 if ( !child->isTableRow() ) { 693 1927 694 if( !beforeChild ) 1928 695 beforeChild = lastChild(); … … 1938 705 return; 1939 706 } else { 1940 kdDebug( 6040 ) << "creating anonymous table row" << endl;707 //kdDebug( 6040 ) << "creating anonymous table row" << endl; 1941 708 row = new (renderArena()) RenderTableRow(0 /* anonymous table */); 1942 709 RenderStyle *newStyle = new RenderStyle(); 1943 710 newStyle->inheritFrom(style()); 1944 newStyle->setDisplay( TABLE_ROW);711 newStyle->setDisplay( TABLE_ROW ); 1945 712 row->setStyle(newStyle); 1946 713 row->setIsAnonymousBox(true); … … 1955 722 1956 723 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 1961 738 RenderContainer::addChild(child,beforeChild); 739 } 740 741 void 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 757 void 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 862 void 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 898 void 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 976 int 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 1142 void 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 1198 void 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 1222 void RenderTableSection::clearGrid() 1223 { 1224 int rows = grid.size(); 1225 while ( rows-- ) { 1226 delete grid[rows].row; 1227 } 1228 } 1229 1230 RenderObject* RenderTableSection::removeChildNode(RenderObject* child) 1231 { 1232 setNeedCellRecalc(); 1233 return RenderContainer::removeChildNode( child ); 1962 1234 } 1963 1235 … … 1965 1237 void RenderTableSection::dump(QTextStream *stream, QString ind) const 1966 1238 { 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 } 1969 1250 RenderContainer::dump(stream,ind); 1970 1251 } … … 1978 1259 // init RenderObject attributes 1979 1260 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 1263 void RenderTableRow::detach(RenderArena* arena) 1264 { 1265 section()->setNeedCellRecalc(); 1266 1267 RenderContainer::detach(arena); 1268 } 1269 1270 void RenderTableRow::setStyle(RenderStyle* style) 1271 { 1272 style->setDisplay(TABLE_ROW); 1273 RenderContainer::setStyle(style); 2007 1274 } 2008 1275 … … 2013 1280 (beforeChild ? beforeChild->renderName() : "0") << " )" << endl; 2014 1281 #endif 2015 RenderTableCell *cell;2016 2017 1282 if (child->element() && child->element()->id() == ID_FORM) { 2018 1283 RenderContainer::addChild(child,beforeChild); … … 2020 1285 } 2021 1286 1287 RenderTableCell *cell; 1288 2022 1289 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); 2028 1296 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); 2045 1304 } 2046 1305 cell->addChild(child); … … 2051 1310 cell = static_cast<RenderTableCell *>(child); 2052 1311 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 ); 2056 1313 2057 1314 RenderContainer::addChild(cell,beforeChild); 2058 1315 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 1320 RenderObject* RenderTableRow::removeChildNode(RenderObject* child) 1321 { 1322 // RenderTableCell detach should do it 1323 // if ( section() ) 1324 // section()->setNeedCellRecalc(); 1325 return RenderContainer::removeChildNode( child ); 2067 1326 } 2068 1327 … … 2070 1329 void RenderTableRow::dump(QTextStream *stream, QString ind) const 2071 1330 { 2072 *stream << " rIndex = " << rIndex;2073 *stream << " ncols = " << ncols;2074 2075 1331 RenderContainer::dump(stream,ind); 2076 1332 } … … 2084 1340 RenderObject *child = firstChild(); 2085 1341 while( child ) { 2086 if (child->isTableCell() && !child->layouted() ) {2087 2088 2089 2090 2091 2092 2093 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(); 2094 1350 } 2095 1351 setLayouted(); … … 2104 1360 _row = -1; 2105 1361 updateFromElement(); 2106 _id = 0;2107 rowHeight = 0;2108 cellPercentageHeight = 0;2109 m_table = 0;2110 rowimpl = 0;2111 1362 setShouldPaintBackgroundOrBorder(true); 2112 1363 _topExtra = 0; 2113 1364 _bottomExtra = 0; 2114 } 2115 2116 RenderTableCell::~RenderTableCell() 2117 { 2118 if (m_table) 2119 m_table->setNeedsCellsRecalc(); 1365 m_percentageHeight = 0; 1366 } 1367 1368 void RenderTableCell::detach(RenderArena* arena) 1369 { 1370 if (parent() && section()) 1371 section()->setNeedCellRecalc(); 1372 1373 RenderFlow::detach(arena); 2120 1374 } 2121 1375 … … 2127 1381 cSpan = tc->colSpan(); 2128 1382 rSpan = tc->rowSpan(); 2129 nWrap = tc->noWrap();2130 1383 } else { 2131 1384 cSpan = rSpan = 1; 2132 nWrap = false;2133 1385 } 2134 1386 } 2135 1387 1388 int RenderTableCell::getCellPercentageHeight() const 1389 { 1390 return m_percentageHeight; 1391 } 1392 1393 void RenderTableCell::setCellPercentageHeight(int h) 1394 { 1395 m_percentageHeight = h; 1396 } 1397 2136 1398 void RenderTableCell::calcMinMaxWidth() 2137 1399 { … … 2141 1403 #endif 2142 1404 2143 //if(minMaxKnown()) return;2144 2145 int oldMin = m_minWidth;2146 int oldMax = m_maxWidth;2147 2148 1405 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 2167 1407 setMinMaxKnown(); 2168 1408 } … … 2189 1429 } 2190 1430 2191 int RenderTableCell::paddingTop() const2192 {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() const2201 {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() const2210 {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() const2219 {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 }2226 1431 2227 1432 void RenderTableCell::repaintRectangle(int x, int y, int w, int h, bool immediate, bool f) … … 2242 1447 { 2243 1448 RenderObject *o = firstChild(); 2244 int offset = paddingTop() ;1449 int offset = paddingTop() + borderTop(); 2245 1450 if ( !o ) return offset; 2246 1451 while ( o->firstChild() ) { 2247 offset += paddingTop() + borderTop(); 1452 if ( !o->isInline() ) 1453 offset += o->paddingTop() + o->borderTop(); 2248 1454 o = o->firstChild(); 2249 1455 } … … 2255 1461 void RenderTableCell::setStyle( RenderStyle *style ) 2256 1462 { 1463 style->setDisplay(TABLE_CELL); 2257 1464 RenderFlow::setStyle( style ); 2258 1465 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 } 2259 1476 } 2260 1477 … … 2271 1488 2272 1489 void 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) 2274 1491 { 2275 1492 2276 1493 #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; 2282 1498 2283 1499 _tx += m_x; … … 2297 1513 2298 1514 void 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 { 2303 1517 int w = width(); 2304 1518 int h = height() + borderTopExtra() + borderBottomExtra(); 2305 1519 _ty -= borderTopExtra(); 2306 2307 int my = KMAX(_ty,_y);2308 int mh;2309 if (_ty<_y)2310 mh= KMAX(0,h-(_y-_ty));2311 else2312 mh = KMIN(_h,h);2313 1520 2314 1521 QColor c = style()->backgroundColor(); … … 2317 1524 if ( !c.isValid() && parent() && parent()->parent() ) // take from rowgroup 2318 1525 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 } 2320 1539 2321 1540 // ### get offsets right in case the bgimage is inherited. … … 2325 1544 if ( !bg && parent() && parent()->parent() ) 2326 1545 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; 2327 1563 2328 1564 if ( bg || c.isValid() ) 2329 1565 paintBackground(p, c, bg, my, mh, _tx, _ty, w, h); 2330 1566 2331 1567 if(style()->hasBorder()) … … 2333 1569 } 2334 1570 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 }2341 1571 2342 1572 #ifndef NDEBUG 2343 1573 void RenderTableCell::dump(QTextStream *stream, QString ind) const 2344 1574 { 2345 *stream << " _row=" << _row;2346 *stream << " _col=" << _col;1575 *stream << " row=" << _row; 1576 *stream << " col=" << _col; 2347 1577 *stream << " rSpan=" << rSpan; 2348 1578 *stream << " cSpan=" << cSpan; 2349 *stream << " _id=" << _id; 2350 *stream << " nWrap=" << nWrap; 1579 // *stream << " nWrap=" << nWrap; 2351 1580 2352 1581 RenderFlow::dump(stream,ind); … … 2364 1593 _span = 1; 2365 1594 updateFromElement(); 2366 _currentCol = 0;2367 _startCol = 0;2368 _id = 0;2369 }2370 2371 RenderTableCol::~RenderTableCol()2372 {2373 1595 } 2374 1596 … … 2379 1601 DOM::HTMLTableColElementImpl *tc = static_cast<DOM::HTMLTableColElementImpl *>(node); 2380 1602 _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 ); 2387 1605 } 2388 1606 … … 2395 1613 2396 1614 if (child->style()->display() == TABLE_COLUMN) 2397 {2398 1615 // these have to come before the table definition! 2399 1616 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 }2406 1617 } 2407 1618 … … 2410 1621 { 2411 1622 *stream << " _span=" << _span; 2412 *stream << " _startCol=" << _startCol;2413 *stream << " _id=" << _id;2414 2415 1623 RenderContainer::dump(stream,ind); 2416 1624 } 2417 1625 #endif 2418 2419 // -------------------------------------------------------------------------2420 2421 RenderTableCaption::RenderTableCaption(DOM::NodeImpl* node)2422 : RenderFlow(node)2423 {2424 }2425 2426 RenderTableCaption::~RenderTableCaption()2427 {2428 }2429 1626 2430 1627 #undef TABLE_DEBUG -
trunk/WebCore/khtml/rendering/render_table.h
r3143 r3351 7 7 * (C) 1999 Lars Knoll (knoll@kde.org) 8 8 * (C) 1999 Antti Koivisto (koivisto@kde.org) 9 * Copyright (C) 2002 Apple Computer, Inc.10 9 * 11 10 * This library is free software; you can redistribute it and/or … … 24 23 * Boston, MA 02111-1307, USA. 25 24 * 25 * $Id$ 26 26 */ 27 27 #ifndef RENDER_TABLE_H … … 47 47 class RenderTableCell; 48 48 class RenderTableCol; 49 class RenderTableCaption;49 class TableLayout; 50 50 51 51 class RenderTable : public RenderFlow … … 82 82 virtual bool isTable() const { return true; } 83 83 84 int getColumnPos(int col) 84 int getColumnPos(int col) const 85 85 { 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; } 107 95 108 96 // overrides … … 110 98 virtual int overflowWidth() const { return width(); } 111 99 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); 114 102 virtual void layout(); 115 103 virtual void calcMinMaxWidth(); … … 118 106 virtual short lineHeight(bool b) const; 119 107 virtual short baselinePosition(bool b) const; 120 108 121 109 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;}127 110 128 111 virtual void position(int x, int y, int from, int len, int width, bool reverse, bool firstLine, int); … … 133 116 virtual int borderBottomExtra(); 134 117 135 void closeRow();136 void setNeedsCellsRecalc();137 void recalcCells();138 139 118 #ifndef NDEBUG 140 119 virtual void dump(QTextStream *stream, QString ind = "") const; 141 120 #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 187 131 }; 188 132 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 196 166 protected: 197 167 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; 258 174 RenderTableSection *head; 259 175 RenderTableSection *foot; 260 176 RenderTableSection *firstBody; 261 177 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; 276 187 }; 277 188 278 189 // ------------------------------------------------------------------------- 279 190 280 class RenderTableSection : public Render Container191 class RenderTableSection : public RenderBox 281 192 { 282 193 public: 283 194 RenderTableSection(DOM::NodeImpl* node); 284 195 ~RenderTableSection(); 196 virtual void detach(RenderArena* arena); 197 198 virtual void setStyle(RenderStyle *style); 285 199 286 200 virtual const char *renderName() const { return "RenderTableSection"; } 287 288 int numRows() { return nrows; }289 201 290 202 // overrides … … 295 207 virtual void position(int, int, int, int, int, bool, bool, int) {} 296 208 297 virtual void setTable(RenderTable *t) { table = t; }298 299 209 #ifndef NDEBUG 300 210 virtual void dump(QTextStream *stream, QString ind = "") const; 301 211 #endif 302 212 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(); 303 258 protected: 304 RenderTable *table;305 int nrows;259 void ensureRows( int numRows ); 260 void clearGrid(); 306 261 }; 307 262 … … 312 267 public: 313 268 RenderTableRow(DOM::NodeImpl* node); 314 ~RenderTableRow(); 315 269 270 virtual void detach(RenderArena* arena); 271 272 virtual void setStyle( RenderStyle* ); 316 273 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; }323 274 324 275 virtual bool isTableRow() const { return true; } … … 326 277 // overrides 327 278 virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0); 279 virtual RenderObject* removeChildNode(RenderObject* child); 328 280 329 281 virtual short lineHeight( bool ) const { return 0; } 330 282 virtual void position(int, int, int, int, int, bool, bool, int) {} 331 283 332 virtual void close();333 334 virtual void repaint(bool immediate=false);335 336 284 virtual void layout(); 337 285 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()); } 339 288 340 289 #ifndef NDEBUG 341 290 virtual void dump(QTextStream *stream, QString ind = "") const; 342 291 #endif 343 344 protected:345 RenderTable *table;346 347 // relative to the current section!348 int rIndex;349 int ncols;350 292 }; 351 293 … … 356 298 public: 357 299 RenderTableCell(DOM::NodeImpl* node); 358 ~RenderTableCell(); 300 301 virtual void detach(RenderArena* arena); 359 302 360 303 virtual const char *renderName() const { return "RenderTableCell"; } … … 365 308 void setCellIndex( long ) { } 366 309 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; } 375 315 376 316 int col() const { return _col; } … … 378 318 int row() const { return _row; } 379 319 void setRow(int r) { _row = r; } 380 381 khtml::LengthType colType();382 320 383 321 // overrides … … 386 324 virtual void setWidth( int width ); 387 325 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 400 327 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; }408 328 409 329 void setCellTopExtra(int p) { _topExtra = p; } 410 330 void setCellBottomExtra(int p) { _bottomExtra = p; } 411 331 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); 417 337 418 338 virtual void close(); … … 428 348 virtual int borderTopExtra() { return _topExtra; } 429 349 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()); } 430 353 431 354 #ifndef NDEBUG … … 440 363 441 364 protected: 442 RenderTable *m_table;443 444 365 virtual void paintBoxDecorations(QPainter *p,int _x, int _y, 445 366 int _w, int _h, int _tx, int _ty); 446 367 447 368 short _row; 448 369 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; 456 373 bool nWrap : 1; 374 int _bottomExtra : 31; 457 375 bool m_widthChanged : 1; 458 459 RenderTableRow *rowimpl; 460 }; 376 377 int m_percentageHeight; 378 }; 379 461 380 462 381 // ------------------------------------------------------------------------- … … 466 385 public: 467 386 RenderTableCol(DOM::NodeImpl* node); 468 ~RenderTableCol();469 387 470 388 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; }475 389 476 390 long span() const { return _span; } … … 478 392 479 393 virtual void addChild(RenderObject *child, RenderObject *beforeChild = 0); 394 395 virtual bool isTableCol() const { return true; } 480 396 481 397 virtual short lineHeight( bool ) const { return 0; } … … 483 399 virtual void layout() {} 484 400 485 virtual void setTable(RenderTable *t) { table = t; }486 487 401 virtual void updateFromElement(); 488 402 … … 492 406 493 407 protected: 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 764 764 case ID_TBODY: 765 765 case ID_TFOOT: 766 n = new HTMLTableSectionElementImpl(docPtr(), id );766 n = new HTMLTableSectionElementImpl(docPtr(), id, false); 767 767 break; 768 768 -
trunk/WebCore/khtml/xml/dom_nodeimpl.cpp
r3098 r3351 69 69 m_active( false ), 70 70 m_styleElement( false ), 71 m_implicit( false ), 71 72 m_rendererNeedsClose( false ) 72 73 { … … 901 902 if (m_active) { *stream << " active"; } 902 903 if (m_styleElement) { *stream << " styleElement"; } 904 if (m_implicit) { *stream << " implicit"; } 903 905 904 906 *stream << " tabIndex=" << m_tabIndex; -
trunk/WebCore/khtml/xml/dom_nodeimpl.h
r3098 r3351 187 187 bool inDocument() const { return m_inDocument; } 188 188 bool styleElement() const { return m_styleElement; } 189 bool implicitNode() const { return m_implicit; } 189 190 void setHasID(bool b=true) { m_hasId = b; } 190 191 void setHasClass(bool b=true) { m_hasClass = b; } … … 396 397 bool m_active : 1; 397 398 bool m_styleElement : 1; // contains stylesheet text 399 bool m_implicit : 1; // implicitely generated by the parser 398 400 bool m_rendererNeedsClose : 1; 399 401 400 // 2 bitsunused402 // 1 bit unused 401 403 }; 402 404
Note:
See TracChangeset
for help on using the changeset viewer.