| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org) |
| 3 * (C) 2002 Dirk Mueller (mueller@kde.org) | 3 * (C) 2002 Dirk Mueller (mueller@kde.org) |
| 4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved. | 4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License. | 9 * version 2 of the License. |
| 10 * | 10 * |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 #include "config.h" | 22 #include "config.h" |
| 23 #include "core/rendering/AutoTableLayout.h" | 23 #include "core/rendering/AutoTableLayout.h" |
| 24 | 24 |
| 25 #include "core/rendering/FastTextAutosizer.h" | 25 #include "core/rendering/FastTextAutosizer.h" |
| 26 #include "core/rendering/RenderTable.h" | 26 #include "core/rendering/RenderTable.h" |
| 27 #include "core/rendering/RenderTableCell.h" | 27 #include "core/rendering/RenderTableCell.h" |
| 28 #include "core/rendering/RenderTableCol.h" | 28 #include "core/rendering/RenderTableCol.h" |
| 29 #include "core/rendering/RenderTableSection.h" | 29 #include "core/rendering/RenderTableSection.h" |
| 30 | 30 |
| 31 using namespace std; | |
| 32 | |
| 33 namespace WebCore { | 31 namespace WebCore { |
| 34 | 32 |
| 35 AutoTableLayout::AutoTableLayout(RenderTable* table) | 33 AutoTableLayout::AutoTableLayout(RenderTable* table) |
| 36 : TableLayout(table) | 34 : TableLayout(table) |
| 37 , m_hasPercent(false) | 35 , m_hasPercent(false) |
| 38 , m_effectiveLogicalWidthDirty(true) | 36 , m_effectiveLogicalWidthDirty(true) |
| 39 { | 37 { |
| 40 } | 38 } |
| 41 | 39 |
| 42 AutoTableLayout::~AutoTableLayout() | 40 AutoTableLayout::~AutoTableLayout() |
| (...skipping 22 matching lines...) Expand all Loading... |
| 65 | 63 |
| 66 if (current.inColSpan || !cell) | 64 if (current.inColSpan || !cell) |
| 67 continue; | 65 continue; |
| 68 | 66 |
| 69 bool cellHasContent = cell->children()->firstChild() || cell->st
yle()->hasBorder() || cell->style()->hasPadding() || cell->style()->hasBackgroun
d(); | 67 bool cellHasContent = cell->children()->firstChild() || cell->st
yle()->hasBorder() || cell->style()->hasPadding() || cell->style()->hasBackgroun
d(); |
| 70 if (cellHasContent) | 68 if (cellHasContent) |
| 71 columnLayout.emptyCellsOnly = false; | 69 columnLayout.emptyCellsOnly = false; |
| 72 | 70 |
| 73 // A cell originates in this column. Ensure we have | 71 // A cell originates in this column. Ensure we have |
| 74 // a min/max width of at least 1px for this column now. | 72 // a min/max width of at least 1px for this column now. |
| 75 columnLayout.minLogicalWidth = max<int>(columnLayout.minLogicalW
idth, cellHasContent ? 1 : 0); | 73 columnLayout.minLogicalWidth = std::max<int>(columnLayout.minLog
icalWidth, cellHasContent ? 1 : 0); |
| 76 columnLayout.maxLogicalWidth = max<int>(columnLayout.maxLogicalW
idth, 1); | 74 columnLayout.maxLogicalWidth = std::max<int>(columnLayout.maxLog
icalWidth, 1); |
| 77 | 75 |
| 78 if (cell->colSpan() == 1) { | 76 if (cell->colSpan() == 1) { |
| 79 columnLayout.minLogicalWidth = max<int>(cell->minPreferredLo
gicalWidth(), columnLayout.minLogicalWidth); | 77 columnLayout.minLogicalWidth = std::max<int>(cell->minPrefer
redLogicalWidth(), columnLayout.minLogicalWidth); |
| 80 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogic
alWidth) { | 78 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogic
alWidth) { |
| 81 columnLayout.maxLogicalWidth = cell->maxPreferredLogical
Width(); | 79 columnLayout.maxLogicalWidth = cell->maxPreferredLogical
Width(); |
| 82 maxContributor = cell; | 80 maxContributor = cell; |
| 83 } | 81 } |
| 84 | 82 |
| 85 // All browsers implement a size limit on the cell's max wid
th. | 83 // All browsers implement a size limit on the cell's max wid
th. |
| 86 // Our limit is based on KHTML's representation that used 16
bits widths. | 84 // Our limit is based on KHTML's representation that used 16
bits widths. |
| 87 // FIXME: Other browsers have a lower limit for the cell's m
ax width. | 85 // FIXME: Other browsers have a lower limit for the cell's m
ax width. |
| 88 const int cCellMaxWidth = 32760; | 86 const int cCellMaxWidth = 32760; |
| 89 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); | 87 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 } | 124 } |
| 127 | 125 |
| 128 // Nav/IE weirdness | 126 // Nav/IE weirdness |
| 129 if (columnLayout.logicalWidth.isFixed()) { | 127 if (columnLayout.logicalWidth.isFixed()) { |
| 130 if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth >
columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { | 128 if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth >
columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { |
| 131 columnLayout.logicalWidth = Length(); | 129 columnLayout.logicalWidth = Length(); |
| 132 fixedContributor = 0; | 130 fixedContributor = 0; |
| 133 } | 131 } |
| 134 } | 132 } |
| 135 | 133 |
| 136 columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, columnLayou
t.minLogicalWidth); | 134 columnLayout.maxLogicalWidth = std::max(columnLayout.maxLogicalWidth, column
Layout.minLogicalWidth); |
| 137 } | 135 } |
| 138 | 136 |
| 139 void AutoTableLayout::fullRecalc() | 137 void AutoTableLayout::fullRecalc() |
| 140 { | 138 { |
| 141 m_hasPercent = false; | 139 m_hasPercent = false; |
| 142 m_effectiveLogicalWidthDirty = true; | 140 m_effectiveLogicalWidthDirty = true; |
| 143 | 141 |
| 144 unsigned nEffCols = m_table->numEffCols(); | 142 unsigned nEffCols = m_table->numEffCols(); |
| 145 m_layoutStruct.resize(nEffCols); | 143 m_layoutStruct.resize(nEffCols); |
| 146 m_layoutStruct.fill(Layout()); | 144 m_layoutStruct.fill(Layout()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two
places below to avoid division by zero. | 220 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two
places below to avoid division by zero. |
| 223 // FIXME: Handle the 0% cases properly. | 221 // FIXME: Handle the 0% cases properly. |
| 224 const float epsilon = 1 / 128.0f; | 222 const float epsilon = 1 / 128.0f; |
| 225 | 223 |
| 226 float remainingPercent = 100; | 224 float remainingPercent = 100; |
| 227 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { | 225 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { |
| 228 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; | 226 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; |
| 229 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; | 227 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; |
| 230 if (scaleColumns) { | 228 if (scaleColumns) { |
| 231 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { | 229 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { |
| 232 float percent = min(static_cast<float>(m_layoutStruct[i].effecti
veLogicalWidth.percent()), remainingPercent); | 230 float percent = std::min(static_cast<float>(m_layoutStruct[i].ef
fectiveLogicalWidth.percent()), remainingPercent); |
| 233 float logicalWidth = static_cast<float>(m_layoutStruct[i].effect
iveMaxLogicalWidth) * 100 / max(percent, epsilon); | 231 float logicalWidth = static_cast<float>(m_layoutStruct[i].effect
iveMaxLogicalWidth) * 100 / std::max(percent, epsilon); |
| 234 maxPercent = max(logicalWidth, maxPercent); | 232 maxPercent = std::max(logicalWidth, maxPercent); |
| 235 remainingPercent -= percent; | 233 remainingPercent -= percent; |
| 236 } else | 234 } else |
| 237 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; | 235 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; |
| 238 } | 236 } |
| 239 } | 237 } |
| 240 | 238 |
| 241 if (scaleColumns) { | 239 if (scaleColumns) { |
| 242 maxNonPercent = maxNonPercent * 100 / max(remainingPercent, epsilon); | 240 maxNonPercent = maxNonPercent * 100 / std::max(remainingPercent, epsilon
); |
| 243 maxWidth = max<int>(maxWidth, static_cast<int>(min(maxNonPercent, static
_cast<float>(tableMaxWidth)))); | 241 maxWidth = std::max<int>(maxWidth, static_cast<int>(std::min(maxNonPerce
nt, static_cast<float>(tableMaxWidth)))); |
| 244 maxWidth = max<int>(maxWidth, static_cast<int>(min(maxPercent, static_ca
st<float>(tableMaxWidth)))); | 242 maxWidth = std::max<int>(maxWidth, static_cast<int>(std::min(maxPercent,
static_cast<float>(tableMaxWidth)))); |
| 245 } | 243 } |
| 246 | 244 |
| 247 maxWidth = max<int>(maxWidth, spanMaxLogicalWidth); | 245 maxWidth = std::max<int>(maxWidth, spanMaxLogicalWidth); |
| 248 } | 246 } |
| 249 | 247 |
| 250 void AutoTableLayout::applyPreferredLogicalWidthQuirks(LayoutUnit& minWidth, Lay
outUnit& maxWidth) const | 248 void AutoTableLayout::applyPreferredLogicalWidthQuirks(LayoutUnit& minWidth, Lay
outUnit& maxWidth) const |
| 251 { | 249 { |
| 252 Length tableLogicalWidth = m_table->style()->logicalWidth(); | 250 Length tableLogicalWidth = m_table->style()->logicalWidth(); |
| 253 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { | 251 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { |
| 254 // |minWidth| is the result of measuring the intrinsic content's size. K
eep it to | 252 // |minWidth| is the result of measuring the intrinsic content's size. K
eep it to |
| 255 // make sure we are *never* smaller than the actual content. | 253 // make sure we are *never* smaller than the actual content. |
| 256 LayoutUnit minContentWidth = minWidth; | 254 LayoutUnit minContentWidth = minWidth; |
| 257 // FIXME: This line looks REALLY suspicious as it could allow the minimu
m | 255 // FIXME: This line looks REALLY suspicious as it could allow the minimu
m |
| 258 // preferred logical width to be smaller than the table content. This ha
s | 256 // preferred logical width to be smaller than the table content. This ha
s |
| 259 // to be cross-checked against other browsers. | 257 // to be cross-checked against other browsers. |
| 260 minWidth = maxWidth = max<int>(minWidth, tableLogicalWidth.value()); | 258 minWidth = maxWidth = std::max<int>(minWidth, tableLogicalWidth.value())
; |
| 261 | 259 |
| 262 const Length& styleMaxLogicalWidth = m_table->style()->logicalMaxWidth()
; | 260 const Length& styleMaxLogicalWidth = m_table->style()->logicalMaxWidth()
; |
| 263 if (styleMaxLogicalWidth.isFixed() && !styleMaxLogicalWidth.isNegative()
) { | 261 if (styleMaxLogicalWidth.isFixed() && !styleMaxLogicalWidth.isNegative()
) { |
| 264 minWidth = min<int>(minWidth, styleMaxLogicalWidth.value()); | 262 minWidth = std::min<int>(minWidth, styleMaxLogicalWidth.value()); |
| 265 minWidth = max(minWidth, minContentWidth); | 263 minWidth = std::max(minWidth, minContentWidth); |
| 266 maxWidth = minWidth; | 264 maxWidth = minWidth; |
| 267 } | 265 } |
| 268 } | 266 } |
| 269 } | 267 } |
| 270 | 268 |
| 271 /* | 269 /* |
| 272 This method takes care of colspans. | 270 This method takes care of colspans. |
| 273 effWidth is the same as width for cells without colspans. If we have colspans,
they get modified. | 271 effWidth is the same as width for cells without colspans. If we have colspans,
they get modified. |
| 274 */ | 272 */ |
| 275 int AutoTableLayout::calcEffectiveLogicalWidth() | 273 int AutoTableLayout::calcEffectiveLogicalWidth() |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 cellMinLogicalWidth -= spacingInRowDirection; | 349 cellMinLogicalWidth -= spacingInRowDirection; |
| 352 cellMaxLogicalWidth -= spacingInRowDirection; | 350 cellMaxLogicalWidth -= spacingInRowDirection; |
| 353 } | 351 } |
| 354 | 352 |
| 355 // adjust table max width if needed | 353 // adjust table max width if needed |
| 356 if (cellLogicalWidth.isPercent()) { | 354 if (cellLogicalWidth.isPercent()) { |
| 357 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent)
{ | 355 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent)
{ |
| 358 // can't satify this condition, treat as variable | 356 // can't satify this condition, treat as variable |
| 359 cellLogicalWidth = Length(); | 357 cellLogicalWidth = Length(); |
| 360 } else { | 358 } else { |
| 361 maxLogicalWidth = max(maxLogicalWidth, static_cast<int>(max(span
MaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percent())); | 359 maxLogicalWidth = std::max(maxLogicalWidth, static_cast<int>(std
::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percen
t())); |
| 362 | 360 |
| 363 // all non percent columns in the span get percent values to sum
up correctly. | 361 // all non percent columns in the span get percent values to sum
up correctly. |
| 364 float percentMissing = cellLogicalWidth.percent() - totalPercent
; | 362 float percentMissing = cellLogicalWidth.percent() - totalPercent
; |
| 365 int totalWidth = 0; | 363 int totalWidth = 0; |
| 366 for (unsigned pos = effCol; pos < lastCol; ++pos) { | 364 for (unsigned pos = effCol; pos < lastCol; ++pos) { |
| 367 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) | 365 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) |
| 368 totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWid
th; | 366 totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWid
th; |
| 369 } | 367 } |
| 370 | 368 |
| 371 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++p
os) { | 369 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++p
os) { |
| 372 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent())
{ | 370 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent())
{ |
| 373 float percent = percentMissing * static_cast<float>(m_la
youtStruct[pos].effectiveMaxLogicalWidth) / totalWidth; | 371 float percent = percentMissing * static_cast<float>(m_la
youtStruct[pos].effectiveMaxLogicalWidth) / totalWidth; |
| 374 totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWid
th; | 372 totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWid
th; |
| 375 percentMissing -= percent; | 373 percentMissing -= percent; |
| 376 if (percent > 0) | 374 if (percent > 0) |
| 377 m_layoutStruct[pos].effectiveLogicalWidth.setValue(P
ercent, percent); | 375 m_layoutStruct[pos].effectiveLogicalWidth.setValue(P
ercent, percent); |
| 378 else | 376 else |
| 379 m_layoutStruct[pos].effectiveLogicalWidth = Length()
; | 377 m_layoutStruct[pos].effectiveLogicalWidth = Length()
; |
| 380 } | 378 } |
| 381 } | 379 } |
| 382 } | 380 } |
| 383 } | 381 } |
| 384 | 382 |
| 385 // make sure minWidth and maxWidth of the spanning cell are honoured | 383 // make sure minWidth and maxWidth of the spanning cell are honoured |
| 386 if (cellMinLogicalWidth > spanMinLogicalWidth) { | 384 if (cellMinLogicalWidth > spanMinLogicalWidth) { |
| 387 if (allColsAreFixed) { | 385 if (allColsAreFixed) { |
| 388 for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++p
os) { | 386 for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++p
os) { |
| 389 int cellLogicalWidth = max(m_layoutStruct[pos].effectiveMinL
ogicalWidth, static_cast<int>(cellMinLogicalWidth * m_layoutStruct[pos].logicalW
idth.value() / fixedWidth)); | 387 int cellLogicalWidth = std::max(m_layoutStruct[pos].effectiv
eMinLogicalWidth, static_cast<int>(cellMinLogicalWidth * m_layoutStruct[pos].log
icalWidth.value() / fixedWidth)); |
| 390 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); | 388 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); |
| 391 cellMinLogicalWidth -= cellLogicalWidth; | 389 cellMinLogicalWidth -= cellLogicalWidth; |
| 392 m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWi
dth; | 390 m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWi
dth; |
| 393 } | 391 } |
| 394 } else if (allColsArePercent) { | 392 } else if (allColsArePercent) { |
| 395 // In this case, we just split the colspan's min amd max widths
following the percentage. | 393 // In this case, we just split the colspan's min amd max widths
following the percentage. |
| 396 int allocatedMinLogicalWidth = 0; | 394 int allocatedMinLogicalWidth = 0; |
| 397 int allocatedMaxLogicalWidth = 0; | 395 int allocatedMaxLogicalWidth = 0; |
| 398 for (unsigned pos = effCol; pos < lastCol; ++pos) { | 396 for (unsigned pos = effCol; pos < lastCol; ++pos) { |
| 399 ASSERT(m_layoutStruct[pos].logicalWidth.isPercent() || m_lay
outStruct[pos].effectiveLogicalWidth.isPercent()); | 397 ASSERT(m_layoutStruct[pos].logicalWidth.isPercent() || m_lay
outStruct[pos].effectiveLogicalWidth.isPercent()); |
| 400 // |allColsArePercent| means that either the logicalWidth *o
r* the effectiveLogicalWidth are percents, handle both of them here. | 398 // |allColsArePercent| means that either the logicalWidth *o
r* the effectiveLogicalWidth are percents, handle both of them here. |
| 401 float percent = m_layoutStruct[pos].logicalWidth.isPercent()
? m_layoutStruct[pos].logicalWidth.percent() : m_layoutStruct[pos].effectiveLog
icalWidth.percent(); | 399 float percent = m_layoutStruct[pos].logicalWidth.isPercent()
? m_layoutStruct[pos].logicalWidth.percent() : m_layoutStruct[pos].effectiveLog
icalWidth.percent(); |
| 402 int columnMinLogicalWidth = static_cast<int>(percent * cellM
inLogicalWidth / totalPercent); | 400 int columnMinLogicalWidth = static_cast<int>(percent * cellM
inLogicalWidth / totalPercent); |
| 403 int columnMaxLogicalWidth = static_cast<int>(percent * cellM
axLogicalWidth / totalPercent); | 401 int columnMaxLogicalWidth = static_cast<int>(percent * cellM
axLogicalWidth / totalPercent); |
| 404 m_layoutStruct[pos].effectiveMinLogicalWidth = max(m_layoutS
truct[pos].effectiveMinLogicalWidth, columnMinLogicalWidth); | 402 m_layoutStruct[pos].effectiveMinLogicalWidth = std::max(m_la
youtStruct[pos].effectiveMinLogicalWidth, columnMinLogicalWidth); |
| 405 m_layoutStruct[pos].effectiveMaxLogicalWidth = columnMaxLogi
calWidth; | 403 m_layoutStruct[pos].effectiveMaxLogicalWidth = columnMaxLogi
calWidth; |
| 406 allocatedMinLogicalWidth += columnMinLogicalWidth; | 404 allocatedMinLogicalWidth += columnMinLogicalWidth; |
| 407 allocatedMaxLogicalWidth += columnMaxLogicalWidth; | 405 allocatedMaxLogicalWidth += columnMaxLogicalWidth; |
| 408 } | 406 } |
| 409 ASSERT(allocatedMinLogicalWidth <= cellMinLogicalWidth); | 407 ASSERT(allocatedMinLogicalWidth <= cellMinLogicalWidth); |
| 410 ASSERT(allocatedMaxLogicalWidth <= cellMaxLogicalWidth); | 408 ASSERT(allocatedMaxLogicalWidth <= cellMaxLogicalWidth); |
| 411 cellMinLogicalWidth -= allocatedMinLogicalWidth; | 409 cellMinLogicalWidth -= allocatedMinLogicalWidth; |
| 412 cellMaxLogicalWidth -= allocatedMaxLogicalWidth; | 410 cellMaxLogicalWidth -= allocatedMaxLogicalWidth; |
| 413 } else { | 411 } else { |
| 414 int remainingMaxLogicalWidth = spanMaxLogicalWidth; | 412 int remainingMaxLogicalWidth = spanMaxLogicalWidth; |
| 415 int remainingMinLogicalWidth = spanMinLogicalWidth; | 413 int remainingMinLogicalWidth = spanMinLogicalWidth; |
| 416 | 414 |
| 417 // Give min to variable first, to fixed second, and to others th
ird. | 415 // Give min to variable first, to fixed second, and to others th
ird. |
| 418 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos
< lastCol; ++pos) { | 416 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos
< lastCol; ++pos) { |
| 419 if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto &
& fixedWidth <= cellMinLogicalWidth) { | 417 if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto &
& fixedWidth <= cellMinLogicalWidth) { |
| 420 int colMinLogicalWidth = max<int>(m_layoutStruct[pos].ef
fectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value()); | 418 int colMinLogicalWidth = std::max<int>(m_layoutStruct[po
s].effectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value()); |
| 421 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); | 419 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); |
| 422 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; | 420 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; |
| 423 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; | 421 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; |
| 424 cellMinLogicalWidth -= colMinLogicalWidth; | 422 cellMinLogicalWidth -= colMinLogicalWidth; |
| 425 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; | 423 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; |
| 426 } | 424 } |
| 427 } | 425 } |
| 428 | 426 |
| 429 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos
< lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) { | 427 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos
< lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) { |
| 430 if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto
&& fixedWidth <= cellMinLogicalWidth)) { | 428 if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto
&& fixedWidth <= cellMinLogicalWidth)) { |
| 431 int colMinLogicalWidth = max<int>(m_layoutStruct[pos].ef
fectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMinLogic
alWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / rem
ainingMaxLogicalWidth : cellMinLogicalWidth)); | 429 int colMinLogicalWidth = std::max<int>(m_layoutStruct[po
s].effectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMin
LogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth)
/ remainingMaxLogicalWidth : cellMinLogicalWidth)); |
| 432 colMinLogicalWidth = min<int>(m_layoutStruct[pos].effect
iveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colMinLog
icalWidth); | 430 colMinLogicalWidth = std::min<int>(m_layoutStruct[pos].e
ffectiveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colM
inLogicalWidth); |
| 433 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; | 431 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; |
| 434 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; | 432 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; |
| 435 cellMinLogicalWidth -= colMinLogicalWidth; | 433 cellMinLogicalWidth -= colMinLogicalWidth; |
| 436 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; | 434 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; |
| 437 } | 435 } |
| 438 } | 436 } |
| 439 } | 437 } |
| 440 } | 438 } |
| 441 if (!cellLogicalWidth.isPercent()) { | 439 if (!cellLogicalWidth.isPercent()) { |
| 442 if (cellMaxLogicalWidth > spanMaxLogicalWidth) { | 440 if (cellMaxLogicalWidth > spanMaxLogicalWidth) { |
| 443 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < la
stCol; ++pos) { | 441 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < la
stCol; ++pos) { |
| 444 int colMaxLogicalWidth = max(m_layoutStruct[pos].effectiveMa
xLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * stat
ic_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogicalWid
th : cellMaxLogicalWidth)); | 442 int colMaxLogicalWidth = std::max(m_layoutStruct[pos].effect
iveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth *
static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogic
alWidth : cellMaxLogicalWidth)); |
| 445 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogic
alWidth; | 443 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogic
alWidth; |
| 446 cellMaxLogicalWidth -= colMaxLogicalWidth; | 444 cellMaxLogicalWidth -= colMaxLogicalWidth; |
| 447 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogical
Width; | 445 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogical
Width; |
| 448 } | 446 } |
| 449 } | 447 } |
| 450 } else { | 448 } else { |
| 451 for (unsigned pos = effCol; pos < lastCol; ++pos) | 449 for (unsigned pos = effCol; pos < lastCol; ++pos) |
| 452 m_layoutStruct[pos].maxLogicalWidth = max(m_layoutStruct[pos].ma
xLogicalWidth, m_layoutStruct[pos].minLogicalWidth); | 450 m_layoutStruct[pos].maxLogicalWidth = std::max(m_layoutStruct[po
s].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth); |
| 453 } | 451 } |
| 454 // treat span ranges consisting of empty cells only as if they had conte
nt | 452 // treat span ranges consisting of empty cells only as if they had conte
nt |
| 455 if (spanHasEmptyCellsOnly) { | 453 if (spanHasEmptyCellsOnly) { |
| 456 for (unsigned pos = effCol; pos < lastCol; ++pos) | 454 for (unsigned pos = effCol; pos < lastCol; ++pos) |
| 457 m_layoutStruct[pos].emptyCellsOnly = false; | 455 m_layoutStruct[pos].emptyCellsOnly = false; |
| 458 } | 456 } |
| 459 } | 457 } |
| 460 m_effectiveLogicalWidthDirty = false; | 458 m_effectiveLogicalWidthDirty = false; |
| 461 | 459 |
| 462 return min(maxLogicalWidth, INT_MAX / 2); | 460 return std::min(maxLogicalWidth, INT_MAX / 2); |
| 463 } | 461 } |
| 464 | 462 |
| 465 /* gets all cells that originate in a column and have a cellspan > 1 | 463 /* gets all cells that originate in a column and have a cellspan > 1 |
| 466 Sorts them by increasing cellspan | 464 Sorts them by increasing cellspan |
| 467 */ | 465 */ |
| 468 void AutoTableLayout::insertSpanCell(RenderTableCell *cell) | 466 void AutoTableLayout::insertSpanCell(RenderTableCell *cell) |
| 469 { | 467 { |
| 470 ASSERT_ARG(cell, cell && cell->colSpan() != 1); | 468 ASSERT_ARG(cell, cell && cell->colSpan() != 1); |
| 471 if (!cell || cell->colSpan() == 1) | 469 if (!cell || cell->colSpan() == 1) |
| 472 return; | 470 return; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 default: | 542 default: |
| 545 break; | 543 break; |
| 546 } | 544 } |
| 547 } | 545 } |
| 548 | 546 |
| 549 // allocate width to percent cols | 547 // allocate width to percent cols |
| 550 if (available > 0 && havePercent) { | 548 if (available > 0 && havePercent) { |
| 551 for (size_t i = 0; i < nEffCols; ++i) { | 549 for (size_t i = 0; i < nEffCols; ++i) { |
| 552 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 550 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
| 553 if (logicalWidth.isPercent()) { | 551 if (logicalWidth.isPercent()) { |
| 554 int cellLogicalWidth = max<int>(m_layoutStruct[i].effectiveMinLo
gicalWidth, minimumValueForLength(logicalWidth, tableLogicalWidth)); | 552 int cellLogicalWidth = std::max<int>(m_layoutStruct[i].effective
MinLogicalWidth, minimumValueForLength(logicalWidth, tableLogicalWidth)); |
| 555 available += m_layoutStruct[i].computedLogicalWidth - cellLogica
lWidth; | 553 available += m_layoutStruct[i].computedLogicalWidth - cellLogica
lWidth; |
| 556 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; | 554 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; |
| 557 } | 555 } |
| 558 } | 556 } |
| 559 if (totalPercent > 100) { | 557 if (totalPercent > 100) { |
| 560 // remove overallocated space from the last columns | 558 // remove overallocated space from the last columns |
| 561 int excess = tableLogicalWidth * (totalPercent - 100) / 100; | 559 int excess = tableLogicalWidth * (totalPercent - 100) / 100; |
| 562 for (unsigned i = nEffCols; i; ) { | 560 for (unsigned i = nEffCols; i; ) { |
| 563 --i; | 561 --i; |
| 564 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { | 562 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { |
| 565 int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidt
h; | 563 int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidt
h; |
| 566 int reduction = min(cellLogicalWidth, excess); | 564 int reduction = std::min(cellLogicalWidth, excess); |
| 567 // the lines below might look inconsistent, but that's the w
ay it's handled in mozilla | 565 // the lines below might look inconsistent, but that's the w
ay it's handled in mozilla |
| 568 excess -= reduction; | 566 excess -= reduction; |
| 569 int newLogicalWidth = max<int>(m_layoutStruct[i].effectiveMi
nLogicalWidth, cellLogicalWidth - reduction); | 567 int newLogicalWidth = std::max<int>(m_layoutStruct[i].effect
iveMinLogicalWidth, cellLogicalWidth - reduction); |
| 570 available += cellLogicalWidth - newLogicalWidth; | 568 available += cellLogicalWidth - newLogicalWidth; |
| 571 m_layoutStruct[i].computedLogicalWidth = newLogicalWidth; | 569 m_layoutStruct[i].computedLogicalWidth = newLogicalWidth; |
| 572 } | 570 } |
| 573 } | 571 } |
| 574 } | 572 } |
| 575 } | 573 } |
| 576 | 574 |
| 577 // then allocate width to fixed cols | 575 // then allocate width to fixed cols |
| 578 if (available > 0) { | 576 if (available > 0) { |
| 579 for (size_t i = 0; i < nEffCols; ++i) { | 577 for (size_t i = 0; i < nEffCols; ++i) { |
| 580 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 578 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
| 581 if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[
i].computedLogicalWidth) { | 579 if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[
i].computedLogicalWidth) { |
| 582 available += m_layoutStruct[i].computedLogicalWidth - logicalWid
th.value(); | 580 available += m_layoutStruct[i].computedLogicalWidth - logicalWid
th.value(); |
| 583 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); | 581 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); |
| 584 } | 582 } |
| 585 } | 583 } |
| 586 } | 584 } |
| 587 | 585 |
| 588 // now satisfy variable | 586 // now satisfy variable |
| 589 if (available > 0 && numAuto) { | 587 if (available > 0 && numAuto) { |
| 590 available += allocAuto; // this gets redistributed | 588 available += allocAuto; // this gets redistributed |
| 591 for (size_t i = 0; i < nEffCols; ++i) { | 589 for (size_t i = 0; i < nEffCols; ++i) { |
| 592 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 590 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
| 593 if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCe
llsOnly) { | 591 if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCe
llsOnly) { |
| 594 int cellLogicalWidth = max<int>(m_layoutStruct[i].computedLogica
lWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effect
iveMaxLogicalWidth) / totalAuto)); | 592 int cellLogicalWidth = std::max<int>(m_layoutStruct[i].computedL
ogicalWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].e
ffectiveMaxLogicalWidth) / totalAuto)); |
| 595 available -= cellLogicalWidth; | 593 available -= cellLogicalWidth; |
| 596 totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth; | 594 totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth; |
| 597 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; | 595 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; |
| 598 } | 596 } |
| 599 } | 597 } |
| 600 } | 598 } |
| 601 | 599 |
| 602 // spread over fixed columns | 600 // spread over fixed columns |
| 603 if (available > 0 && numFixed) { | 601 if (available > 0 && numFixed) { |
| 604 for (size_t i = 0; i < nEffCols; ++i) { | 602 for (size_t i = 0; i < nEffCols; ++i) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 | 724 |
| 727 int pos = 0; | 725 int pos = 0; |
| 728 for (size_t i = 0; i < nEffCols; ++i) { | 726 for (size_t i = 0; i < nEffCols; ++i) { |
| 729 m_table->setColumnPosition(i, pos); | 727 m_table->setColumnPosition(i, pos); |
| 730 pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing(
); | 728 pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing(
); |
| 731 } | 729 } |
| 732 m_table->setColumnPosition(m_table->columnPositions().size() - 1, pos); | 730 m_table->setColumnPosition(m_table->columnPositions().size() - 1, pos); |
| 733 } | 731 } |
| 734 | 732 |
| 735 } | 733 } |
| OLD | NEW |