Changeset 71262 in webkit
- Timestamp:
- Nov 3, 2010 1:44:49 PM (13 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r71260 r71262 1 2010-11-03 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Dave Hyatt. 4 5 Made table column width allocation algorithms use logical widths. 6 7 Part of: Make tables work with vertical text 8 https://bugs.webkit.org/show_bug.cgi?id=46417 9 10 No new tests since tables don’t support different block flows yet. 11 12 * rendering/AutoTableLayout.cpp: 13 (WebCore::AutoTableLayout::AutoTableLayout): 14 (WebCore::AutoTableLayout::recalcColumn): 15 (WebCore::AutoTableLayout::fullRecalc): 16 (WebCore::AutoTableLayout::computePreferredLogicalWidths): 17 (WebCore::AutoTableLayout::calcEffectiveLogicalWidth): 18 (WebCore::AutoTableLayout::insertSpanCell): 19 (WebCore::AutoTableLayout::layout): 20 * rendering/AutoTableLayout.h: 21 (WebCore::AutoTableLayout::Layout::Layout): 22 * rendering/FixedTableLayout.cpp: 23 (WebCore::FixedTableLayout::calcWidthArray): 24 (WebCore::FixedTableLayout::computePreferredLogicalWidths): 25 (WebCore::FixedTableLayout::layout): 26 * rendering/FixedTableLayout.h: 27 * rendering/RenderTable.h: 28 (WebCore::RenderTable::bordersPaddingAndSpacingInRowDirection): Renamed, but not changed yet. 29 1 30 2010-11-03 No'am Rosenthal <noam.rosenthal@nokia.com> 2 31 -
trunk/WebCore/rendering/AutoTableLayout.cpp
r71251 r71262 2 2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org) 3 3 * (C) 2002 Dirk Mueller (mueller@kde.org) 4 * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved. 5 5 * 6 6 * This library is free software; you can redistribute it and/or … … 35 35 : TableLayout(table) 36 36 , m_hasPercent(false) 37 , m_eff WidthDirty(true)37 , m_effectiveLogicalWidthDirty(true) 38 38 { 39 39 } … … 43 43 } 44 44 45 /* recalculates the full structure needed to do layouting and minmax calculations.46 This is usually calculated on the fly, but needs to be done fully when table cells change47 dynamically48 */49 45 void AutoTableLayout::recalcColumn(int effCol) 50 46 { 51 Layout &l = m_layoutStruct[effCol]; 52 53 RenderObject* child = m_table->firstChild(); 54 // first we iterate over all rows. 47 Layout& columnLayout = m_layoutStruct[effCol]; 55 48 56 49 RenderTableCell* fixedContributor = 0; 57 50 RenderTableCell* maxContributor = 0; 58 51 59 while (child) {52 for (RenderObject* child = m_table->firstChild(); child; child = child->nextSibling()) { 60 53 if (child->isTableCol()) 61 54 toRenderTableCol(child)->computePreferredLogicalWidths(); … … 69 62 bool cellHasContent = cell && !current.inColSpan && (cell->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding()); 70 63 if (cellHasContent) 71 l.emptyCellsOnly = false;64 columnLayout.emptyCellsOnly = false; 72 65 73 if (current.inColSpan )66 if (current.inColSpan || !cell) 74 67 continue; 75 if (cell && cell->colSpan() == 1) { 68 69 if (cell->colSpan() == 1) { 76 70 // A cell originates in this column. Ensure we have 77 71 // a min/max width of at least 1px for this column now. 78 l.minWidth = max(l.minWidth, cellHasContent ? 1 : 0);79 l.maxWidth = max(l.maxWidth, 1);72 columnLayout.minLogicalWidth = max(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0); 73 columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, 1); 80 74 if (cell->preferredLogicalWidthsDirty()) 81 75 cell->computePreferredLogicalWidths(); 82 l.minWidth = max(cell->minPreferredLogicalWidth(), l.minWidth);83 if (cell->maxPreferredLogicalWidth() > l.maxWidth) {84 l.maxWidth = cell->maxPreferredLogicalWidth();76 columnLayout.minLogicalWidth = max(cell->minPreferredLogicalWidth(), columnLayout.minLogicalWidth); 77 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) { 78 columnLayout.maxLogicalWidth = cell->maxPreferredLogicalWidth(); 85 79 maxContributor = cell; 86 80 } 87 81 88 Length w= cell->styleOrColLogicalWidth();82 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); 89 83 // FIXME: What is this arbitrary value? 90 if ( w.rawValue() > 32760)91 w.setRawValue(32760);92 if ( w.isNegative())93 w.setValue(0);94 switch ( w.type()) {84 if (cellLogicalWidth.rawValue() > 32760) 85 cellLogicalWidth.setRawValue(32760); 86 if (cellLogicalWidth.isNegative()) 87 cellLogicalWidth.setValue(0); 88 switch (cellLogicalWidth.type()) { 95 89 case Fixed: 96 90 // ignore width=0 97 if ( w.value() > 0 && (int)l.width.type() != Percent) {98 int wval = cell->computeBorderBoxLogicalWidth(w.value());99 if ( l.width.isFixed()) {91 if (cellLogicalWidth.value() > 0 && columnLayout.logicalWidth.type() != Percent) { 92 int logicalWidth = cell->computeBorderBoxLogicalWidth(cellLogicalWidth.value()); 93 if (columnLayout.logicalWidth.isFixed()) { 100 94 // Nav/IE weirdness 101 if (( wval > l.width.value()) ||102 (( l.width.value() == wval) && (maxContributor == cell))) {103 l.width.setValue(wval);95 if ((logicalWidth > columnLayout.logicalWidth.value()) || 96 ((columnLayout.logicalWidth.value() == logicalWidth) && (maxContributor == cell))) { 97 columnLayout.logicalWidth.setValue(logicalWidth); 104 98 fixedContributor = cell; 105 99 } 106 100 } else { 107 l.width.setValue(Fixed, wval);101 columnLayout.logicalWidth.setValue(Fixed, logicalWidth); 108 102 fixedContributor = cell; 109 103 } … … 112 106 case Percent: 113 107 m_hasPercent = true; 114 if ( w.isPositive() && (!l.width.isPercent() || w.rawValue() > l.width.rawValue()))115 l.width = w;108 if (cellLogicalWidth.isPositive() && (!columnLayout.logicalWidth.isPercent() || cellLogicalWidth.rawValue() > columnLayout.logicalWidth.rawValue())) 109 columnLayout.logicalWidth = cellLogicalWidth; 116 110 break; 117 111 case Relative: 118 112 // FIXME: Need to understand this case and whether it makes sense to compare values 119 113 // which are not necessarily of the same type. 120 if ( w.isAuto() || (w.isRelative() && w.value() > l.width.rawValue()))121 l.width = w;114 if (cellLogicalWidth.isAuto() || (cellLogicalWidth.isRelative() && cellLogicalWidth.value() > columnLayout.logicalWidth.rawValue())) 115 columnLayout.logicalWidth = cellLogicalWidth; 122 116 default: 123 117 break; 124 118 } 125 } else { 126 if (cell && (!effCol || section->primaryCellAt(i, effCol-1) != cell)) { 127 // This spanning cell originates in this column. Ensure we have 128 // a min/max width of at least 1px for this column now. 129 l.minWidth = max(l.minWidth, cellHasContent ? 1 : 0); 130 l.maxWidth = max(l.maxWidth, 1); 131 insertSpanCell(cell); 132 } 133 } 134 } 135 } 136 child = child->nextSibling(); 119 } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) { 120 // This spanning cell originates in this column. Ensure we have 121 // a min/max width of at least 1px for this column now. 122 columnLayout.minLogicalWidth = max(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0); 123 columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, 1); 124 insertSpanCell(cell); 125 } 126 } 127 } 137 128 } 138 129 139 130 // Nav/IE weirdness 140 if ( l.width.isFixed()) {141 if (m_table->document()->inQuirksMode() && l.maxWidth > l.width.value() && fixedContributor != maxContributor) {142 l.width = Length();131 if (columnLayout.logicalWidth.isFixed()) { 132 if (m_table->document()->inQuirksMode() && columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { 133 columnLayout.logicalWidth = Length(); 143 134 fixedContributor = 0; 144 135 } 145 136 } 146 137 147 l.maxWidth = max(l.maxWidth, l.minWidth); 148 149 // ### we need to add col elements as well 138 columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, columnLayout.minLogicalWidth); 150 139 } 151 140 … … 153 142 { 154 143 m_hasPercent = false; 155 m_eff WidthDirty = true;144 m_effectiveLogicalWidthDirty = true; 156 145 157 146 int nEffCols = m_table->numEffCols(); … … 160 149 m_spanCells.fill(0); 161 150 162 RenderObject *child = m_table->firstChild(); 163 Length grpWidth; 164 int cCol = 0; 165 while (child) { 166 if (child->isTableCol()) { 167 RenderTableCol *col = toRenderTableCol(child); 168 int span = col->span(); 169 if (col->firstChild()) { 170 grpWidth = col->style()->width(); 171 } else { 172 Length w = col->style()->width(); 173 if (w.isAuto()) 174 w = grpWidth; 175 if ((w.isFixed() || w.isPercent()) && w.isZero()) 176 w = Length(); 177 int cEffCol = m_table->colToEffCol(cCol); 178 if (!w.isAuto() && span == 1 && cEffCol < nEffCols) { 179 if (m_table->spanOfEffCol(cEffCol) == 1) { 180 m_layoutStruct[cEffCol].width = w; 181 if (w.isFixed() && m_layoutStruct[cEffCol].maxWidth < w.value()) 182 m_layoutStruct[cEffCol].maxWidth = w.value(); 183 } 184 } 185 cCol += span; 186 } 187 } else { 188 break; 189 } 190 191 RenderObject *next = child->firstChild(); 151 RenderObject* child = m_table->firstChild(); 152 Length groupLogicalWidth; 153 int currentColumn = 0; 154 while (child && child->isTableCol()) { 155 RenderTableCol* col = toRenderTableCol(child); 156 int span = col->span(); 157 if (col->firstChild()) 158 groupLogicalWidth = col->style()->logicalWidth(); 159 else { 160 Length colLogicalWidth = col->style()->logicalWidth(); 161 if (colLogicalWidth.isAuto()) 162 colLogicalWidth = groupLogicalWidth; 163 if ((colLogicalWidth.isFixed() || colLogicalWidth.isPercent()) && colLogicalWidth.isZero()) 164 colLogicalWidth = Length(); 165 int effCol = m_table->colToEffCol(currentColumn); 166 if (!colLogicalWidth.isAuto() && span == 1 && effCol < nEffCols && m_table->spanOfEffCol(effCol) == 1) { 167 m_layoutStruct[effCol].logicalWidth = colLogicalWidth; 168 if (colLogicalWidth.isFixed() && m_layoutStruct[effCol].maxLogicalWidth < colLogicalWidth.value()) 169 m_layoutStruct[effCol].maxLogicalWidth = colLogicalWidth.value(); 170 } 171 currentColumn += span; 172 } 173 174 RenderObject* next = child->firstChild(); 192 175 if (!next) 193 176 next = child->nextSibling(); 194 177 if (!next && child->parent()->isTableCol()) { 195 178 next = child->parent()->nextSibling(); 196 gr pWidth = Length();179 groupLogicalWidth = Length(); 197 180 } 198 181 child = next; 199 182 } 200 201 183 202 184 for (int i = 0; i < nEffCols; i++) … … 204 186 } 205 187 188 // FIXME: This needs to be adapted for vertical writing modes. 206 189 static bool shouldScaleColumns(RenderTable* table) 207 190 { … … 241 224 fullRecalc(); 242 225 243 int spanMax Width = calcEffectiveWidth();226 int spanMaxLogicalWidth = calcEffectiveLogicalWidth(); 244 227 minWidth = 0; 245 228 maxWidth = 0; … … 253 236 254 237 int remainingPercent = 100 * percentScaleFactor; 255 for ( unsigned int i = 0; i < m_layoutStruct.size(); i++) {256 minWidth += m_layoutStruct[i].eff MinWidth;257 maxWidth += m_layoutStruct[i].eff MaxWidth;238 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { 239 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; 240 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; 258 241 if (scaleColumns) { 259 if (m_layoutStruct[i].eff Width.isPercent()) {260 int percent = min(m_layoutStruct[i].eff Width.rawValue(), remainingPercent);261 float pw = static_cast<float>(m_layoutStruct[i].effMaxWidth) * 100 * percentScaleFactor / max(percent, epsilon);262 maxPercent = max( pw, maxPercent);242 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { 243 int percent = min(m_layoutStruct[i].effectiveLogicalWidth.rawValue(), remainingPercent); 244 float logicalWidth = static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) * 100 * percentScaleFactor / max(percent, epsilon); 245 maxPercent = max(logicalWidth, maxPercent); 263 246 remainingPercent -= percent; 264 247 } else 265 maxNonPercent += m_layoutStruct[i].eff MaxWidth;248 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; 266 249 } 267 250 } … … 273 256 } 274 257 275 maxWidth = max(maxWidth, spanMax Width);276 277 int b s = m_table->bordersPaddingAndSpacing();278 minWidth += b s;279 maxWidth += b s;280 281 Length t w = m_table->style()->width();282 if (t w.isFixed() && tw.value() > 0) {283 minWidth = max(minWidth, t w.value());258 maxWidth = max(maxWidth, spanMaxLogicalWidth); 259 260 int bordersPaddingAndSpacing = m_table->bordersPaddingAndSpacingInRowDirection(); 261 minWidth += bordersPaddingAndSpacing; 262 maxWidth += bordersPaddingAndSpacing; 263 264 Length tableLogicalWidth = m_table->style()->logicalWidth(); 265 if (tableLogicalWidth.isFixed() && tableLogicalWidth.value() > 0) { 266 minWidth = max(minWidth, tableLogicalWidth.value()); 284 267 maxWidth = minWidth; 285 268 } … … 290 273 effWidth is the same as width for cells without colspans. If we have colspans, they get modified. 291 274 */ 292 int AutoTableLayout::calcEffective Width()293 { 294 float tMaxWidth = 0;295 296 unsigned int nEffCols = m_layoutStruct.size();297 int hspacing= m_table->hBorderSpacing();298 299 for ( unsigned int i = 0; i < nEffCols; i++) {300 m_layoutStruct[i].eff Width = m_layoutStruct[i].width;301 m_layoutStruct[i].eff MinWidth = m_layoutStruct[i].minWidth;302 m_layoutStruct[i].eff MaxWidth = m_layoutStruct[i].maxWidth;303 } 304 305 for ( unsigned int i = 0; i < m_spanCells.size(); i++) {306 RenderTableCell *cell = m_spanCells[i];275 int AutoTableLayout::calcEffectiveLogicalWidth() 276 { 277 float maxLogicalWidth = 0; 278 279 size_t nEffCols = m_layoutStruct.size(); 280 int spacingInRowDirection = m_table->hBorderSpacing(); 281 282 for (size_t i = 0; i < nEffCols; ++i) { 283 m_layoutStruct[i].effectiveLogicalWidth = m_layoutStruct[i].logicalWidth; 284 m_layoutStruct[i].effectiveMinLogicalWidth = m_layoutStruct[i].minLogicalWidth; 285 m_layoutStruct[i].effectiveMaxLogicalWidth = m_layoutStruct[i].maxLogicalWidth; 286 } 287 288 for (size_t i = 0; i < m_spanCells.size(); ++i) { 289 RenderTableCell* cell = m_spanCells[i]; 307 290 if (!cell) 308 291 break; 292 309 293 int span = cell->colSpan(); 310 294 311 Length w= cell->styleOrColLogicalWidth();312 if (! w.isRelative() && w.isZero())313 w= Length(); // make it Auto314 315 int col = m_table->colToEffCol(cell->col());316 unsigned int lastCol = col;317 int c MinWidth = cell->minPreferredLogicalWidth() + hspacing;318 float c MaxWidth = cell->maxPreferredLogicalWidth() + hspacing;295 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); 296 if (!cellLogicalWidth.isRelative() && cellLogicalWidth.isZero()) 297 cellLogicalWidth = Length(); // make it Auto 298 299 int effCol = m_table->colToEffCol(cell->col()); 300 size_t lastCol = effCol; 301 int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRowDirection; 302 float cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRowDirection; 319 303 int totalPercent = 0; 320 int minWidth = 0;321 float maxWidth = 0;304 int spanMinLogicalWidth = 0; 305 float spanMaxLogicalWidth = 0; 322 306 bool allColsArePercent = true; 323 307 bool allColsAreFixed = true; … … 326 310 int fixedWidth = 0; 327 311 while (lastCol < nEffCols && span > 0) { 328 switch (m_layoutStruct[lastCol].width.type()) { 312 Layout& columnLayout = m_layoutStruct[lastCol]; 313 switch (columnLayout.logicalWidth.type()) { 329 314 case Percent: 330 totalPercent += m_layoutStruct[lastCol].width.rawValue();315 totalPercent += columnLayout.logicalWidth.rawValue(); 331 316 allColsAreFixed = false; 332 317 break; 333 318 case Fixed: 334 if ( m_layoutStruct[lastCol].width.value() > 0) {335 fixedWidth += m_layoutStruct[lastCol].width.value();319 if (columnLayout.logicalWidth.value() > 0) { 320 fixedWidth += columnLayout.logicalWidth.value(); 336 321 allColsArePercent = false; 337 322 // IE resets effWidth to Auto here, but this breaks the konqueror about page and seems to be some bad … … 351 336 // <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr> 352 337 // </table> 353 if (! m_layoutStruct[lastCol].effWidth.isPercent()) {354 m_layoutStruct[lastCol].effWidth = Length();338 if (!columnLayout.effectiveLogicalWidth.isPercent()) { 339 columnLayout.effectiveLogicalWidth = Length(); 355 340 allColsArePercent = false; 356 } 357 else 358 totalPercent += m_layoutStruct[lastCol].effWidth.rawValue(); 341 } else 342 totalPercent += columnLayout.effectiveLogicalWidth.rawValue(); 359 343 allColsAreFixed = false; 360 344 } 361 if (! m_layoutStruct[lastCol].emptyCellsOnly)345 if (!columnLayout.emptyCellsOnly) 362 346 spanHasEmptyCellsOnly = false; 363 347 span -= m_table->spanOfEffCol(lastCol); 364 minWidth += m_layoutStruct[lastCol].effMinWidth;365 maxWidth += m_layoutStruct[lastCol].effMaxWidth;348 spanMinLogicalWidth += columnLayout.effectiveMinLogicalWidth; 349 spanMaxLogicalWidth += columnLayout.effectiveMaxLogicalWidth; 366 350 lastCol++; 367 c MinWidth -= hspacing;368 c MaxWidth -= hspacing;351 cellMinLogicalWidth -= spacingInRowDirection; 352 cellMaxLogicalWidth -= spacingInRowDirection; 369 353 } 370 354 371 355 // adjust table max width if needed 372 if ( w.isPercent()) {373 if (totalPercent > w.rawValue() || allColsArePercent) {356 if (cellLogicalWidth.isPercent()) { 357 if (totalPercent > cellLogicalWidth.rawValue() || allColsArePercent) { 374 358 // can't satify this condition, treat as variable 375 w= Length();359 cellLogicalWidth = Length(); 376 360 } else { 377 float spanMax = max(maxWidth, cMaxWidth); 378 tMaxWidth = max(tMaxWidth, spanMax * 100 * percentScaleFactor / w.rawValue()); 361 maxLogicalWidth = max(maxLogicalWidth, max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 * percentScaleFactor / cellLogicalWidth.rawValue()); 379 362 380 363 // all non percent columns in the span get percent values to sum up correctly. 381 int percentMissing = w.rawValue() - totalPercent;364 int percentMissing = cellLogicalWidth.rawValue() - totalPercent; 382 365 float totalWidth = 0; 383 for (unsigned int pos = col; pos < lastCol; pos++) {384 if (! (m_layoutStruct[pos].effWidth.isPercent()))385 totalWidth += m_layoutStruct[pos].eff MaxWidth;386 } 387 388 for (unsigned int pos = col; pos < lastCol && totalWidth > 0; pos++) {389 if (! (m_layoutStruct[pos].effWidth.isPercent())) {390 int percent = static_cast<int>(percentMissing * static_cast<float>(m_layoutStruct[pos].eff MaxWidth) / totalWidth);391 totalWidth -= m_layoutStruct[pos].eff MaxWidth;366 for (unsigned pos = effCol; pos < lastCol; ++pos) { 367 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) 368 totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWidth; 369 } 370 371 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++pos) { 372 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) { 373 int percent = static_cast<int>(percentMissing * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / totalWidth); 374 totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth; 392 375 percentMissing -= percent; 393 376 if (percent > 0) 394 m_layoutStruct[pos].eff Width.setRawValue(Percent, percent);377 m_layoutStruct[pos].effectiveLogicalWidth.setRawValue(Percent, percent); 395 378 else 396 m_layoutStruct[pos].eff Width = Length();379 m_layoutStruct[pos].effectiveLogicalWidth = Length(); 397 380 } 398 381 } 399 400 382 } 401 383 } 402 384 403 385 // make sure minWidth and maxWidth of the spanning cell are honoured 404 if (c MinWidth > minWidth) {386 if (cellMinLogicalWidth > spanMinLogicalWidth) { 405 387 if (allColsAreFixed) { 406 for (unsigned int pos = col; fixedWidth > 0 && pos < lastCol; pos++) { 407 int w = max(m_layoutStruct[pos].effMinWidth, cMinWidth * m_layoutStruct[pos].width.value() / fixedWidth); 408 fixedWidth -= m_layoutStruct[pos].width.value(); 409 cMinWidth -= w; 410 m_layoutStruct[pos].effMinWidth = w; 411 } 412 388 for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++pos) { 389 int cellLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, cellMinLogicalWidth * m_layoutStruct[pos].logicalWidth.value() / fixedWidth); 390 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); 391 cellMinLogicalWidth -= cellLogicalWidth; 392 m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWidth; 393 } 413 394 } else { 414 float maxw = maxWidth;415 int minw = minWidth;395 float remainingMaxLogicalWidth = spanMaxLogicalWidth; 396 int remainingMinLogicalWidth = spanMinLogicalWidth; 416 397 417 398 // Give min to variable first, to fixed second, and to others third. 418 for (unsigned int pos = col; maxw >= 0 && pos < lastCol; pos++) {419 if (m_layoutStruct[pos]. width.isFixed() && haveAuto && fixedWidth <= cMinWidth) {420 int w = max(m_layoutStruct[pos].effMinWidth, m_layoutStruct[pos].width.value());421 fixedWidth -= m_layoutStruct[pos]. width.value();422 minw -= m_layoutStruct[pos].effMinWidth;423 maxw -= m_layoutStruct[pos].effMaxWidth;424 c MinWidth -= w;425 m_layoutStruct[pos].eff MinWidth = w;399 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol; ++pos) { 400 if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth) { 401 int colMinLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value()); 402 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); 403 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth; 404 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth; 405 cellMinLogicalWidth -= colMinLogicalWidth; 406 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLogicalWidth; 426 407 } 427 408 } 428 409 429 for (unsigned int pos = col; maxw >= 0 && pos < lastCol && minw < cMinWidth; pos++) { 430 if (!(m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth)) { 431 int w = max(m_layoutStruct[pos].effMinWidth, static_cast<int>(maxw ? cMinWidth * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / maxw : cMinWidth)); 432 w = min(m_layoutStruct[pos].effMinWidth+(cMinWidth-minw), w); 433 434 maxw -= m_layoutStruct[pos].effMaxWidth; 435 minw -= m_layoutStruct[pos].effMinWidth; 436 cMinWidth -= w; 437 m_layoutStruct[pos].effMinWidth = w; 410 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) { 411 if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth)) { 412 int colMinLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMinLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / remainingMaxLogicalWidth : cellMinLogicalWidth)); 413 colMinLogicalWidth = min(m_layoutStruct[pos].effectiveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colMinLogicalWidth); 414 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth; 415 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth; 416 cellMinLogicalWidth -= colMinLogicalWidth; 417 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLogicalWidth; 438 418 } 439 419 } 440 420 } 441 421 } 442 if (! (w.isPercent())) {443 if (c MaxWidth > maxWidth) {444 for (unsigned int pos = col; maxWidth >= 0 && pos < lastCol; pos++) {445 int w = max(m_layoutStruct[pos].effMaxWidth, static_cast<int>(maxWidth ? cMaxWidth * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / maxWidth : cMaxWidth));446 maxWidth -= m_layoutStruct[pos].effMaxWidth;447 c MaxWidth -= w;448 m_layoutStruct[pos].eff MaxWidth = w;422 if (!cellLogicalWidth.isPercent()) { 423 if (cellMaxLogicalWidth > spanMaxLogicalWidth) { 424 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < lastCol; ++pos) { 425 int colMaxLogicalWidth = max(m_layoutStruct[pos].effectiveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogicalWidth : cellMaxLogicalWidth)); 426 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth; 427 cellMaxLogicalWidth -= colMaxLogicalWidth; 428 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogicalWidth; 449 429 } 450 430 } 451 431 } else { 452 for (unsigned int pos = col; pos < lastCol; pos++)453 m_layoutStruct[pos].max Width = max(m_layoutStruct[pos].maxWidth, m_layoutStruct[pos].minWidth);432 for (unsigned pos = effCol; pos < lastCol; ++pos) 433 m_layoutStruct[pos].maxLogicalWidth = max(m_layoutStruct[pos].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth); 454 434 } 455 435 // treat span ranges consisting of empty cells only as if they had content 456 if (spanHasEmptyCellsOnly) 457 for (unsigned int pos = col; pos < lastCol; pos++)436 if (spanHasEmptyCellsOnly) { 437 for (unsigned pos = effCol; pos < lastCol; ++pos) 458 438 m_layoutStruct[pos].emptyCellsOnly = false; 459 } 460 m_effWidthDirty = false; 461 462 return static_cast<int>(min(tMaxWidth, INT_MAX / 2.0f)); 439 } 440 } 441 m_effectiveLogicalWidthDirty = false; 442 443 return static_cast<int>(min(maxLogicalWidth, INT_MAX / 2.0f)); 463 444 } 464 445 … … 468 449 void AutoTableLayout::insertSpanCell(RenderTableCell *cell) 469 450 { 451 ASSERT_ARG(cell, cell && cell->colSpan() != 1); 470 452 if (!cell || cell->colSpan() == 1) 471 453 return; … … 492 474 { 493 475 // table layout based on the values collected in the layout structure. 494 int table Width = m_table->width() - m_table->bordersPaddingAndSpacing();495 int available = table Width;496 int nEffCols = m_table->numEffCols();497 498 if (nEffCols != (int)m_layoutStruct.size()) {476 int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection(); 477 int available = tableLogicalWidth; 478 size_t nEffCols = m_table->numEffCols(); 479 480 if (nEffCols != m_layoutStruct.size()) { 499 481 fullRecalc(); 500 482 nEffCols = m_table->numEffCols(); 501 483 } 502 484 503 if (m_eff WidthDirty)504 calcEffective Width();485 if (m_effectiveLogicalWidthDirty) 486 calcEffectiveLogicalWidth(); 505 487 506 488 bool havePercent = false; … … 512 494 int totalPercent = 0; 513 495 int allocAuto = 0; 514 intnumAutoEmptyCellsOnly = 0;496 unsigned numAutoEmptyCellsOnly = 0; 515 497 516 498 // fill up every cell with its minWidth 517 for ( int i = 0; i < nEffCols; i++) {518 int w = m_layoutStruct[i].effMinWidth;519 m_layoutStruct[i].c alcWidth = w;520 available -= w;521 Length& width = m_layoutStruct[i].effWidth;522 switch ( width.type()) {499 for (size_t i = 0; i < nEffCols; ++i) { 500 int cellLogicalWidth = m_layoutStruct[i].effectiveMinLogicalWidth; 501 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; 502 available -= cellLogicalWidth; 503 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 504 switch (logicalWidth.type()) { 523 505 case Percent: 524 506 havePercent = true; 525 totalPercent += width.rawValue();507 totalPercent += logicalWidth.rawValue(); 526 508 break; 527 509 case Relative: 528 totalRelative += width.value();510 totalRelative += logicalWidth.value(); 529 511 break; 530 512 case Fixed: 531 513 numFixed++; 532 totalFixed += m_layoutStruct[i].eff MaxWidth;514 totalFixed += m_layoutStruct[i].effectiveMaxLogicalWidth; 533 515 // fall through 534 516 break; 535 517 case Auto: 536 518 case Static: 537 if (m_layoutStruct[i].emptyCellsOnly) 538 numAutoEmptyCellsOnly++; 519 if (m_layoutStruct[i].emptyCellsOnly) 520 numAutoEmptyCellsOnly++; 539 521 else { 540 522 numAuto++; 541 totalAuto += m_layoutStruct[i].eff MaxWidth;542 allocAuto += w;523 totalAuto += m_layoutStruct[i].effectiveMaxLogicalWidth; 524 allocAuto += cellLogicalWidth; 543 525 } 544 526 break; … … 550 532 // allocate width to percent cols 551 533 if (available > 0 && havePercent) { 552 for ( int i = 0; i < nEffCols; i++) {553 Length &width = m_layoutStruct[i].effWidth;554 if ( width.isPercent()) {555 int w = max(int(m_layoutStruct[i].effMinWidth), width.calcMinValue(tableWidth));556 available += m_layoutStruct[i].c alcWidth - w;557 m_layoutStruct[i].c alcWidth = w;534 for (size_t i = 0; i < nEffCols; ++i) { 535 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 536 if (logicalWidth.isPercent()) { 537 int cellLogicalWidth = max(m_layoutStruct[i].effectiveMinLogicalWidth, logicalWidth.calcMinValue(tableLogicalWidth)); 538 available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth; 539 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; 558 540 } 559 541 } 560 542 if (totalPercent > 100 * percentScaleFactor) { 561 543 // remove overallocated space from the last columns 562 int excess = table Width*(totalPercent - 100 * percentScaleFactor) / (100 * percentScaleFactor);563 for (int i = nEffCols -1; i >= 0; i--) {564 if (m_layoutStruct[i].eff Width.isPercent()) {565 int w = m_layoutStruct[i].calcWidth;566 int reduction = min( w, excess);544 int excess = tableLogicalWidth * (totalPercent - 100 * percentScaleFactor) / (100 * percentScaleFactor); 545 for (int i = nEffCols - 1; i >= 0; --i) { 546 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { 547 int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidth; 548 int reduction = min(cellLogicalWidth, excess); 567 549 // the lines below might look inconsistent, but that's the way it's handled in mozilla 568 550 excess -= reduction; 569 int new Width = max(static_cast<int>(m_layoutStruct[i].effMinWidth), w- reduction);570 available += w - newWidth;571 m_layoutStruct[i].c alcWidth = newWidth;551 int newLogicalWidth = max(m_layoutStruct[i].effectiveMinLogicalWidth, cellLogicalWidth - reduction); 552 available += cellLogicalWidth - newLogicalWidth; 553 m_layoutStruct[i].computedLogicalWidth = newLogicalWidth; 572 554 } 573 555 } … … 577 559 // then allocate width to fixed cols 578 560 if (available > 0) { 579 for ( int i = 0; i < nEffCols; ++i) {580 Length &width = m_layoutStruct[i].effWidth;581 if ( width.isFixed() && width.value() > m_layoutStruct[i].calcWidth) {582 available += m_layoutStruct[i].c alcWidth - width.value();583 m_layoutStruct[i].c alcWidth = width.value();561 for (size_t i = 0; i < nEffCols; ++i) { 562 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 563 if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[i].computedLogicalWidth) { 564 available += m_layoutStruct[i].computedLogicalWidth - logicalWidth.value(); 565 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); 584 566 } 585 567 } … … 588 570 // now satisfy relative 589 571 if (available > 0) { 590 for ( int i = 0; i < nEffCols; i++) {591 Length &width = m_layoutStruct[i].effWidth;592 if ( width.isRelative() && width.value() != 0) {572 for (size_t i = 0; i < nEffCols; ++i) { 573 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 574 if (logicalWidth.isRelative() && logicalWidth.value() != 0) { 593 575 // width=0* gets effMinWidth. 594 int w = width.value() * tableWidth / totalRelative;595 available += m_layoutStruct[i].c alcWidth - w;596 m_layoutStruct[i].c alcWidth = w;576 int cellLogicalWidth = logicalWidth.value() * tableLogicalWidth / totalRelative; 577 available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth; 578 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; 597 579 } 598 580 } … … 602 584 if (available > 0 && numAuto) { 603 585 available += allocAuto; // this gets redistributed 604 for ( int i = 0; i < nEffCols; i++) {605 Length &width = m_layoutStruct[i].effWidth;606 if ( width.isAuto() && totalAuto != 0&& !m_layoutStruct[i].emptyCellsOnly) {607 int w = max(m_layoutStruct[i].calcWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effMaxWidth) / totalAuto));608 available -= w;609 totalAuto -= m_layoutStruct[i].eff MaxWidth;610 m_layoutStruct[i].c alcWidth = w;586 for (size_t i = 0; i < nEffCols; ++i) { 587 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 588 if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCellsOnly) { 589 int cellLogicalWidth = max(m_layoutStruct[i].computedLogicalWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalAuto)); 590 available -= cellLogicalWidth; 591 totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth; 592 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; 611 593 } 612 594 } … … 615 597 // spread over fixed columns 616 598 if (available > 0 && numFixed) { 617 // still have some width to spread, distribute to fixed columns 618 for (int i = 0; i < nEffCols; i++) { 619 Length &width = m_layoutStruct[i].effWidth; 620 if (width.isFixed()) { 621 int w = static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effMaxWidth) / totalFixed); 622 available -= w; 623 totalFixed -= m_layoutStruct[i].effMaxWidth; 624 m_layoutStruct[i].calcWidth += w; 599 for (size_t i = 0; i < nEffCols; ++i) { 600 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 601 if (logicalWidth.isFixed()) { 602 int cellLogicalWidth = static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalFixed); 603 available -= cellLogicalWidth; 604 totalFixed -= m_layoutStruct[i].effectiveMaxLogicalWidth; 605 m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; 625 606 } 626 607 } … … 629 610 // spread over percent colums 630 611 if (available > 0 && m_hasPercent && totalPercent < 100 * percentScaleFactor) { 631 // still have some width to spread, distribute weighted to percent columns632 for (int i = 0; i < nEffCols; i++) {633 Length &width = m_layoutStruct[i].effWidth;634 if (width.isPercent()) {635 int w = available * width.rawValue() / totalPercent;636 available -= w;637 totalPercent -= width.rawValue();638 m_layoutStruct[i].calcWidth += w;639 if (!available || !totalPercent)break;612 for (size_t i = 0; i < nEffCols; ++i) { 613 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 614 if (logicalWidth.isPercent()) { 615 int cellLogicalWidth = available * logicalWidth.rawValue() / totalPercent; 616 available -= cellLogicalWidth; 617 totalPercent -= logicalWidth.rawValue(); 618 m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; 619 if (!available || !totalPercent) 620 break; 640 621 } 641 622 } … … 646 627 int total = nEffCols - numAutoEmptyCellsOnly; 647 628 // still have some width to spread 648 int i = nEffCols; 649 while (i--) { 629 for (int i = nEffCols - 1; i >= 0; --i) { 650 630 // variable columns with empty cells only don't get any width 651 if (m_layoutStruct[i].eff Width.isAuto() && m_layoutStruct[i].emptyCellsOnly)631 if (m_layoutStruct[i].effectiveLogicalWidth.isAuto() && m_layoutStruct[i].emptyCellsOnly) 652 632 continue; 653 int w= available / total;654 available -= w;633 int cellLogicalWidth = available / total; 634 available -= cellLogicalWidth; 655 635 total--; 656 m_layoutStruct[i].c alcWidth += w;636 m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth; 657 637 } 658 638 } … … 668 648 // This is basically the reverse of how we grew the cells. 669 649 if (available < 0) { 670 int mw= 0;671 for (int i = nEffCols -1; i >= 0; i--) {672 Length &width = m_layoutStruct[i].effWidth;673 if ( width.isAuto())674 mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;650 int logicalWidthBeyondMin = 0; 651 for (int i = nEffCols - 1; i >= 0; --i) { 652 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 653 if (logicalWidth.isAuto()) 654 logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; 675 655 } 676 656 677 for (int i = nEffCols -1; i >= 0 && mw > 0; i--) {678 Length &width = m_layoutStruct[i].effWidth;679 if ( width.isAuto()) {680 int minMaxDiff = m_layoutStruct[i].c alcWidth-m_layoutStruct[i].effMinWidth;681 int reduce = available * minMaxDiff / mw;682 m_layoutStruct[i].c alcWidth += reduce;657 for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) { 658 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 659 if (logicalWidth.isAuto()) { 660 int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; 661 int reduce = available * minMaxDiff / logicalWidthBeyondMin; 662 m_layoutStruct[i].computedLogicalWidth += reduce; 683 663 available -= reduce; 684 mw-= minMaxDiff;664 logicalWidthBeyondMin -= minMaxDiff; 685 665 if (available >= 0) 686 666 break; … … 690 670 691 671 if (available < 0) { 692 int mw= 0;693 for (int i = nEffCols -1; i >= 0; i--) {694 Length& width = m_layoutStruct[i].effWidth;695 if ( width.isRelative())696 mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;672 int logicalWidthBeyondMin = 0; 673 for (int i = nEffCols - 1; i >= 0; --i) { 674 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 675 if (logicalWidth.isRelative()) 676 logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; 697 677 } 698 678 699 for (int i = nEffCols -1; i >= 0 && mw > 0; i--) {700 Length& width = m_layoutStruct[i].effWidth;701 if ( width.isRelative()) {702 int minMaxDiff = m_layoutStruct[i].c alcWidth-m_layoutStruct[i].effMinWidth;703 int reduce = available * minMaxDiff / mw;704 m_layoutStruct[i].c alcWidth += reduce;679 for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) { 680 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 681 if (logicalWidth.isRelative()) { 682 int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; 683 int reduce = available * minMaxDiff / logicalWidthBeyondMin; 684 m_layoutStruct[i].computedLogicalWidth += reduce; 705 685 available -= reduce; 706 mw-= minMaxDiff;686 logicalWidthBeyondMin -= minMaxDiff; 707 687 if (available >= 0) 708 688 break; … … 712 692 713 693 if (available < 0) { 714 int mw= 0;715 for (int i = nEffCols -1; i >= 0; i--) {716 Length& width = m_layoutStruct[i].effWidth;717 if ( width.isFixed())718 mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;694 int logicalWidthBeyondMin = 0; 695 for (int i = nEffCols - 1; i >= 0; --i) { 696 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 697 if (logicalWidth.isFixed()) 698 logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; 719 699 } 720 700 721 for (int i = nEffCols -1; i >= 0 && mw > 0; i--) {722 Length& width = m_layoutStruct[i].effWidth;723 if ( width.isFixed()) {724 int minMaxDiff = m_layoutStruct[i].c alcWidth-m_layoutStruct[i].effMinWidth;725 int reduce = available * minMaxDiff / mw;726 m_layoutStruct[i].c alcWidth += reduce;701 for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) { 702 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 703 if (logicalWidth.isFixed()) { 704 int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; 705 int reduce = available * minMaxDiff / logicalWidthBeyondMin; 706 m_layoutStruct[i].computedLogicalWidth += reduce; 727 707 available -= reduce; 728 mw-= minMaxDiff;708 logicalWidthBeyondMin -= minMaxDiff; 729 709 if (available >= 0) 730 710 break; … … 734 714 735 715 if (available < 0) { 736 int mw= 0;737 for (int i = nEffCols -1; i >= 0; i--) {738 Length& width = m_layoutStruct[i].effWidth;739 if ( width.isPercent())740 mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;716 int logicalWidthBeyondMin = 0; 717 for (int i = nEffCols - 1; i >= 0; --i) { 718 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 719 if (logicalWidth.isPercent()) 720 logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; 741 721 } 742 722 743 for (int i = nEffCols-1; i >= 0 && mw> 0; i--) {744 Length& width = m_layoutStruct[i].effWidth;745 if ( width.isPercent()) {746 int minMaxDiff = m_layoutStruct[i].c alcWidth-m_layoutStruct[i].effMinWidth;747 int reduce = available * minMaxDiff / mw;748 m_layoutStruct[i].c alcWidth += reduce;723 for (int i = nEffCols-1; i >= 0 && logicalWidthBeyondMin > 0; i--) { 724 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 725 if (logicalWidth.isPercent()) { 726 int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth; 727 int reduce = available * minMaxDiff / logicalWidthBeyondMin; 728 m_layoutStruct[i].computedLogicalWidth += reduce; 749 729 available -= reduce; 750 mw-= minMaxDiff;730 logicalWidthBeyondMin -= minMaxDiff; 751 731 if (available >= 0) 752 732 break; … … 757 737 758 738 int pos = 0; 759 for ( int i = 0; i < nEffCols; i++) {739 for (size_t i = 0; i < nEffCols; ++i) { 760 740 m_table->columnPositions()[i] = pos; 761 pos += m_layoutStruct[i].c alcWidth + m_table->hBorderSpacing();741 pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing(); 762 742 } 763 743 m_table->columnPositions()[m_table->columnPositions().size() - 1] = pos; -
trunk/WebCore/rendering/AutoTableLayout.h
r71138 r71262 39 39 virtual void layout(); 40 40 41 pr otected:41 private: 42 42 void fullRecalc(); 43 43 void recalcColumn(int effCol); 44 44 45 int calcEffective Width();45 int calcEffectiveLogicalWidth(); 46 46 47 47 void insertSpanCell(RenderTableCell*); … … 49 49 struct Layout { 50 50 Layout() 51 : minWidth(0) 52 , maxWidth(0) 53 , effMinWidth(0) 54 , effMaxWidth(0) 55 , calcWidth(0) 56 , emptyCellsOnly(true) {} 57 Length width; 58 Length effWidth; 59 int minWidth; 60 int maxWidth; 61 int effMinWidth; 62 int effMaxWidth; 63 int calcWidth; 51 : minLogicalWidth(0) 52 , maxLogicalWidth(0) 53 , effectiveMinLogicalWidth(0) 54 , effectiveMaxLogicalWidth(0) 55 , computedLogicalWidth(0) 56 , emptyCellsOnly(true) 57 { 58 } 59 60 Length logicalWidth; 61 Length effectiveLogicalWidth; 62 int minLogicalWidth; 63 int maxLogicalWidth; 64 int effectiveMinLogicalWidth; 65 int effectiveMaxLogicalWidth; 66 int computedLogicalWidth; 64 67 bool emptyCellsOnly; 65 68 }; … … 68 71 Vector<RenderTableCell*, 4> m_spanCells; 69 72 bool m_hasPercent : 1; 70 mutable bool m_eff WidthDirty : 1;73 mutable bool m_effectiveLogicalWidthDirty : 1; 71 74 }; 72 75 -
trunk/WebCore/rendering/FixedTableLayout.cpp
r71251 r71262 2 2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org) 3 3 * (C) 2002 Dirk Mueller (mueller@kde.org) 4 * Copyright (C) 2003, 200 6 Apple Computer,Inc.4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. 5 5 * 6 6 * This library is free software; you can redistribute it and/or … … 90 90 int currentEffectiveColumn = 0; 91 91 Length grpWidth; 92 while (child) { 93 if (child->isTableCol()) { 94 RenderTableCol* col = toRenderTableCol(child); 95 if (col->firstChild()) 96 grpWidth = col->style()->width(); 97 else { 98 Length w = col->style()->width(); 99 if (w.isAuto()) 100 w = grpWidth; 101 int effWidth = 0; 102 if (w.isFixed() && w.value() > 0) 103 effWidth = w.value(); 104 105 int span = col->span(); 106 while (span) { 107 int spanInCurrentEffectiveColumn; 108 if (currentEffectiveColumn >= nEffCols) { 109 m_table->appendColumn(span); 92 while (child && child->isTableCol()) { 93 RenderTableCol* col = toRenderTableCol(child); 94 if (col->firstChild()) 95 grpWidth = col->style()->logicalWidth(); 96 else { 97 Length w = col->style()->logicalWidth(); 98 if (w.isAuto()) 99 w = grpWidth; 100 int effWidth = 0; 101 if (w.isFixed() && w.value() > 0) 102 effWidth = w.value(); 103 104 int span = col->span(); 105 while (span) { 106 int spanInCurrentEffectiveColumn; 107 if (currentEffectiveColumn >= nEffCols) { 108 m_table->appendColumn(span); 109 nEffCols++; 110 m_width.append(Length()); 111 spanInCurrentEffectiveColumn = span; 112 } else { 113 if (span < m_table->spanOfEffCol(currentEffectiveColumn)) { 114 m_table->splitColumn(currentEffectiveColumn, span); 110 115 nEffCols++; 111 116 m_width.append(Length()); 112 spanInCurrentEffectiveColumn = span;113 } else {114 if (span < m_table->spanOfEffCol(currentEffectiveColumn)) {115 m_table->splitColumn(currentEffectiveColumn, span);116 nEffCols++;117 m_width.append(Length());118 }119 spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn);120 117 } 121 if ((w.isFixed() || w.isPercent()) && w.isPositive()) {122 m_width[currentEffectiveColumn].setRawValue(w.type(), w.rawValue() * spanInCurrentEffectiveColumn);123 usedWidth += effWidth * spanInCurrentEffectiveColumn;124 }125 span -=spanInCurrentEffectiveColumn;126 currentEffectiveColumn++;127 }128 }129 toRenderTableCol(child)->computePreferredLogicalWidths();130 } else131 break;118 spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn); 119 } 120 if ((w.isFixed() || w.isPercent()) && w.isPositive()) { 121 m_width[currentEffectiveColumn].setRawValue(w.type(), w.rawValue() * spanInCurrentEffectiveColumn); 122 usedWidth += effWidth * spanInCurrentEffectiveColumn; 123 } 124 span -= spanInCurrentEffectiveColumn; 125 currentEffectiveColumn++; 126 } 127 } 128 col->computePreferredLogicalWidths(); 132 129 133 130 RenderObject* next = child->firstChild(); … … 202 199 // 203 200 // The maximum width is max(minWidth, tableWidth). 204 int b s = m_table->bordersPaddingAndSpacing();205 206 int table Width = m_table->style()->width().isFixed() ? m_table->style()->width().value() - bs: 0;207 int mw = calcWidthArray(table Width) + bs;208 209 minWidth = max(mw, table Width);201 int bordersPaddingAndSpacing = m_table->bordersPaddingAndSpacingInRowDirection(); 202 203 int tableLogicalWidth = m_table->style()->logicalWidth().isFixed() ? m_table->style()->logicalWidth().value() - bordersPaddingAndSpacing : 0; 204 int mw = calcWidthArray(tableLogicalWidth) + bordersPaddingAndSpacing; 205 206 minWidth = max(mw, tableLogicalWidth); 210 207 maxWidth = minWidth; 211 208 … … 224 221 // We can achieve this effect by making the maxwidth of fixed tables with percentage 225 222 // widths be infinite. 226 if (m_table->document()->inQuirksMode() && m_table->style()->width().isPercent() 227 && maxWidth < TABLE_MAX_WIDTH) 223 if (m_table->document()->inQuirksMode() && m_table->style()->logicalWidth().isPercent() && maxWidth < TABLE_MAX_WIDTH) 228 224 maxWidth = TABLE_MAX_WIDTH; 229 225 } … … 231 227 void FixedTableLayout::layout() 232 228 { 233 int table Width = m_table->width() - m_table->bordersPaddingAndSpacing();229 int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection(); 234 230 int nEffCols = m_table->numEffCols(); 235 231 Vector<int> calcWidth(nEffCols, 0); … … 250 246 totalFixedWidth += calcWidth[i]; 251 247 } else if (m_width[i].isPercent()) { 252 calcWidth[i] = m_width[i].calcValue(table Width);248 calcWidth[i] = m_width[i].calcValue(tableLogicalWidth); 253 249 totalPercentWidth += calcWidth[i]; 254 250 totalRawPercent += m_width[i].rawValue(); … … 261 257 int hspacing = m_table->hBorderSpacing(); 262 258 int totalWidth = totalFixedWidth + totalPercentWidth; 263 if (!numAuto || totalWidth > table Width) {259 if (!numAuto || totalWidth > tableLogicalWidth) { 264 260 // If there are no auto columns, or if the total is too wide, take 265 261 // what we have and scale it to fit as necessary. 266 if (totalWidth != table Width) {262 if (totalWidth != tableLogicalWidth) { 267 263 // Fixed widths only scale up 268 if (totalFixedWidth && totalWidth < table Width) {264 if (totalFixedWidth && totalWidth < tableLogicalWidth) { 269 265 totalFixedWidth = 0; 270 266 for (int i = 0; i < nEffCols; i++) { 271 267 if (m_width[i].isFixed()) { 272 calcWidth[i] = calcWidth[i] * table Width / totalWidth;268 calcWidth[i] = calcWidth[i] * tableLogicalWidth / totalWidth; 273 269 totalFixedWidth += calcWidth[i]; 274 270 } … … 279 275 for (int i = 0; i < nEffCols; i++) { 280 276 if (m_width[i].isPercent()) { 281 calcWidth[i] = m_width[i].rawValue() * (table Width - totalFixedWidth) / totalRawPercent;277 calcWidth[i] = m_width[i].rawValue() * (tableLogicalWidth - totalFixedWidth) / totalRawPercent; 282 278 totalPercentWidth += calcWidth[i]; 283 279 } … … 288 284 } else { 289 285 // Divide the remaining width among the auto columns. 290 int remainingWidth = table Width - totalFixedWidth - totalPercentWidth - hspacing * (autoSpan - numAuto);286 int remainingWidth = tableLogicalWidth - totalFixedWidth - totalPercentWidth - hspacing * (autoSpan - numAuto); 291 287 int lastAuto = 0; 292 288 for (int i = 0; i < nEffCols; i++) { … … 306 302 if (remainingWidth) 307 303 calcWidth[lastAuto] += remainingWidth; 308 totalWidth = table Width;309 } 310 311 if (totalWidth < table Width) {304 totalWidth = tableLogicalWidth; 305 } 306 307 if (totalWidth < tableLogicalWidth) { 312 308 // Spread extra space over columns. 313 int remainingWidth = table Width - totalWidth;309 int remainingWidth = tableLogicalWidth - totalWidth; 314 310 int total = nEffCols; 315 311 while (total) { -
trunk/WebCore/rendering/FixedTableLayout.h
r68276 r71262 37 37 virtual void layout(); 38 38 39 pr otected:39 private: 40 40 int calcWidthArray(int tableWidth); 41 41 -
trunk/WebCore/rendering/RenderTable.h
r69437 r71262 109 109 } 110 110 111 int bordersPaddingAndSpacing () const111 int bordersPaddingAndSpacingInRowDirection() const 112 112 { 113 113 return borderLeft() + borderRight() +
Note: See TracChangeset
for help on using the changeset viewer.