summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/AutoTableLayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/AutoTableLayout.cpp')
-rw-r--r--Source/WebCore/rendering/AutoTableLayout.cpp245
1 files changed, 134 insertions, 111 deletions
diff --git a/Source/WebCore/rendering/AutoTableLayout.cpp b/Source/WebCore/rendering/AutoTableLayout.cpp
index 4cd8f8764..b0cf6bd71 100644
--- a/Source/WebCore/rendering/AutoTableLayout.cpp
+++ b/Source/WebCore/rendering/AutoTableLayout.cpp
@@ -22,10 +22,12 @@
#include "config.h"
#include "AutoTableLayout.h"
+#include "RenderChildIterator.h"
#include "RenderTable.h"
#include "RenderTableCell.h"
#include "RenderTableCol.h"
#include "RenderTableSection.h"
+#include "RenderView.h"
namespace WebCore {
@@ -44,20 +46,20 @@ void AutoTableLayout::recalcColumn(unsigned effCol)
{
Layout& columnLayout = m_layoutStruct[effCol];
- RenderTableCell* fixedContributor = 0;
- RenderTableCell* maxContributor = 0;
+ RenderTableCell* fixedContributor = nullptr;
+ RenderTableCell* maxContributor = nullptr;
- for (RenderObject* child = m_table->firstChild(); child; child = child->nextSibling()) {
- if (child->isRenderTableCol()){
+ for (auto& child : childrenOfType<RenderObject>(*m_table)) {
+ if (is<RenderTableCol>(child)) {
// RenderTableCols don't have the concept of preferred logical width, but we need to clear their dirty bits
// so that if we call setPreferredWidthsDirty(true) on a col or one of its descendants, we'll mark it's
// ancestors as dirty.
- toRenderTableCol(child)->clearPreferredLogicalWidthsDirtyBits();
- } else if (child->isTableSection()) {
- RenderTableSection* section = toRenderTableSection(child);
- unsigned numRows = section->numRows();
- for (unsigned i = 0; i < numRows; i++) {
- RenderTableSection::CellStruct current = section->cellAt(i, effCol);
+ downcast<RenderTableCol>(child).clearPreferredLogicalWidthsDirtyBits();
+ } else if (is<RenderTableSection>(child)) {
+ auto& section = downcast<RenderTableSection>(child);
+ unsigned numRows = section.numRows();
+ for (unsigned i = 0; i < numRows; ++i) {
+ RenderTableSection::CellStruct current = section.cellAt(i, effCol);
RenderTableCell* cell = current.primaryCell();
if (current.inColSpan || !cell)
@@ -69,30 +71,31 @@ void AutoTableLayout::recalcColumn(unsigned effCol)
// A cell originates in this column. Ensure we have
// a min/max width of at least 1px for this column now.
- columnLayout.minLogicalWidth = std::max<int>(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0);
- columnLayout.maxLogicalWidth = std::max<int>(columnLayout.maxLogicalWidth, 1);
+ columnLayout.minLogicalWidth = std::max<float>(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0);
+ columnLayout.maxLogicalWidth = std::max<float>(columnLayout.maxLogicalWidth, 1);
if (cell->colSpan() == 1) {
- columnLayout.minLogicalWidth = std::max<int>(cell->minPreferredLogicalWidth(), columnLayout.minLogicalWidth);
- if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) {
- columnLayout.maxLogicalWidth = cell->maxPreferredLogicalWidth();
+ columnLayout.minLogicalWidth = std::max(cell->minPreferredLogicalWidth().ceilToFloat(), columnLayout.minLogicalWidth);
+ float maxPreferredWidth = cell->maxPreferredLogicalWidth().ceilToFloat();
+ if (maxPreferredWidth > columnLayout.maxLogicalWidth) {
+ columnLayout.maxLogicalWidth = maxPreferredWidth;
maxContributor = cell;
}
// All browsers implement a size limit on the cell's max width.
// Our limit is based on KHTML's representation that used 16 bits widths.
// FIXME: Other browsers have a lower limit for the cell's max width.
- const int cCellMaxWidth = 32760;
+ const float cCellMaxWidth = 32760;
Length cellLogicalWidth = cell->styleOrColLogicalWidth();
if (cellLogicalWidth.value() > cCellMaxWidth)
- cellLogicalWidth.setValue(cCellMaxWidth);
+ cellLogicalWidth.setValue(Fixed, cCellMaxWidth);
if (cellLogicalWidth.isNegative())
- cellLogicalWidth.setValue(0);
+ cellLogicalWidth.setValue(Fixed, 0);
switch (cellLogicalWidth.type()) {
case Fixed:
// ignore width=0
- if (cellLogicalWidth.isPositive() && !columnLayout.logicalWidth.isPercent()) {
- int logicalWidth = cell->adjustBorderBoxLogicalWidthForBoxSizing(cellLogicalWidth.value());
+ if (cellLogicalWidth.isPositive() && !columnLayout.logicalWidth.isPercentOrCalculated()) {
+ float logicalWidth = cell->adjustBorderBoxLogicalWidthForBoxSizing(cellLogicalWidth.value());
if (columnLayout.logicalWidth.isFixed()) {
// Nav/IE weirdness
if ((logicalWidth > columnLayout.logicalWidth.value())
@@ -108,7 +111,7 @@ void AutoTableLayout::recalcColumn(unsigned effCol)
break;
case Percent:
m_hasPercent = true;
- if (cellLogicalWidth.isPositive() && (!columnLayout.logicalWidth.isPercent() || cellLogicalWidth.value() > columnLayout.logicalWidth.value()))
+ if (cellLogicalWidth.isPositive() && (!columnLayout.logicalWidth.isPercent() || cellLogicalWidth.percent() > columnLayout.logicalWidth.percent()))
columnLayout.logicalWidth = cellLogicalWidth;
break;
case Relative:
@@ -120,7 +123,7 @@ void AutoTableLayout::recalcColumn(unsigned effCol)
default:
break;
}
- } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) {
+ } else if (!effCol || section.primaryCellAt(i, effCol - 1) != cell) {
// This spanning cell originates in this column. Insert the cell into spanning cells list.
insertSpanCell(cell);
}
@@ -132,7 +135,7 @@ void AutoTableLayout::recalcColumn(unsigned effCol)
if (columnLayout.logicalWidth.isFixed()) {
if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() && fixedContributor != maxContributor) {
columnLayout.logicalWidth = Length();
- fixedContributor = 0;
+ fixedContributor = nullptr;
}
}
@@ -158,7 +161,7 @@ void AutoTableLayout::fullRecalc()
Length colLogicalWidth = column->style().logicalWidth();
if (colLogicalWidth.isAuto())
colLogicalWidth = groupLogicalWidth;
- if ((colLogicalWidth.isFixed() || colLogicalWidth.isPercent()) && colLogicalWidth.isZero())
+ if ((colLogicalWidth.isFixed() || colLogicalWidth.isPercentOrCalculated()) && colLogicalWidth.isZero())
colLogicalWidth = Length();
unsigned effCol = m_table->colToEffCol(currentColumn);
unsigned span = column->span();
@@ -179,32 +182,50 @@ void AutoTableLayout::fullRecalc()
recalcColumn(i);
}
+static bool shouldScaleColumnsForParent(const RenderTable& table)
+{
+ RenderBlock* containingBlock = table.containingBlock();
+ while (containingBlock && !is<RenderView>(containingBlock)) {
+ // It doesn't matter if our table is auto or fixed: auto means we don't
+ // scale. Fixed doesn't care if we do or not because it doesn't depend
+ // on the cell contents' preferred widths.
+ if (is<RenderTableCell>(containingBlock))
+ return false;
+ containingBlock = containingBlock->containingBlock();
+ }
+ return true;
+}
+
// FIXME: This needs to be adapted for vertical writing modes.
-static bool shouldScaleColumns(RenderTable* table)
+static bool shouldScaleColumnsForSelf(RenderTable* table)
{
+ // Normally, scale all columns to satisfy this from CSS2.2:
+ // "A percentage value for a column width is relative to the table width.
+ // If the table has 'width: auto', a percentage represents a constraint on the column's width"
+
// A special case. If this table is not fixed width and contained inside
// a cell, then don't bloat the maxwidth by examining percentage growth.
bool scale = true;
while (table) {
- Length tw = table->style().width();
- if ((tw.isAuto() || tw.isPercent()) && !table->isOutOfFlowPositioned()) {
- RenderBlock* cb = table->containingBlock();
- while (cb && !cb->isRenderView() && !cb->isTableCell() &&
- cb->style().width().isAuto() && !cb->isOutOfFlowPositioned())
- cb = cb->containingBlock();
-
- table = 0;
- if (cb && cb->isTableCell() &&
- (cb->style().width().isAuto() || cb->style().width().isPercent())) {
- RenderTableCell* cell = toRenderTableCell(cb);
- if (cell->colSpan() > 1 || cell->table()->style().width().isAuto())
+ Length tableWidth = table->style().width();
+ if ((tableWidth.isAuto() || tableWidth.isPercentOrCalculated()) && !table->isOutOfFlowPositioned()) {
+ RenderBlock* containingBlock = table->containingBlock();
+ while (containingBlock && !is<RenderView>(*containingBlock) && !is<RenderTableCell>(*containingBlock)
+ && containingBlock->style().width().isAuto() && !containingBlock->isOutOfFlowPositioned())
+ containingBlock = containingBlock->containingBlock();
+
+ table = nullptr;
+ if (is<RenderTableCell>(containingBlock)
+ && (containingBlock->style().width().isAuto() || containingBlock->style().width().isPercentOrCalculated())) {
+ RenderTableCell& cell = downcast<RenderTableCell>(*containingBlock);
+ if (cell.colSpan() > 1 || cell.table()->style().width().isAuto())
scale = false;
else
- table = cell->table();
+ table = cell.table();
}
}
else
- table = 0;
+ table = nullptr;
}
return scale;
}
@@ -213,12 +234,12 @@ void AutoTableLayout::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, Layout
{
fullRecalc();
- int spanMaxLogicalWidth = calcEffectiveLogicalWidth();
+ float spanMaxLogicalWidth = calcEffectiveLogicalWidth();
minWidth = 0;
maxWidth = 0;
float maxPercent = 0;
float maxNonPercent = 0;
- bool scaleColumns = shouldScaleColumns(m_table);
+ bool scaleColumnsForSelf = shouldScaleColumnsForSelf(m_table);
// We substitute 0 percent by (epsilon / percentScaleFactor) percent in two places below to avoid division by zero.
// FIXME: Handle the 0% cases properly.
@@ -228,10 +249,10 @@ void AutoTableLayout::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, Layout
for (size_t i = 0; i < m_layoutStruct.size(); ++i) {
minWidth += m_layoutStruct[i].effectiveMinLogicalWidth;
maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth;
- if (scaleColumns) {
+ if (scaleColumnsForSelf) {
if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) {
- float percent = std::min(static_cast<float>(m_layoutStruct[i].effectiveLogicalWidth.percent()), remainingPercent);
- float logicalWidth = static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) * 100 / std::max(percent, epsilon);
+ float percent = std::min(m_layoutStruct[i].effectiveLogicalWidth.percent(), remainingPercent);
+ float logicalWidth = m_layoutStruct[i].effectiveMaxLogicalWidth * 100 / std::max(percent, epsilon);
maxPercent = std::max(logicalWidth, maxPercent);
remainingPercent -= percent;
} else
@@ -239,32 +260,34 @@ void AutoTableLayout::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, Layout
}
}
- if (scaleColumns) {
+ if (scaleColumnsForSelf) {
maxNonPercent = maxNonPercent * 100 / std::max(remainingPercent, epsilon);
- maxWidth = std::max<int>(maxWidth, static_cast<int>(std::min(maxNonPercent, static_cast<float>(tableMaxWidth))));
- maxWidth = std::max<int>(maxWidth, static_cast<int>(std::min(maxPercent, static_cast<float>(tableMaxWidth))));
+ m_scaledWidthFromPercentColumns = LayoutUnit(std::min<float>(maxNonPercent, tableMaxWidth));
+ m_scaledWidthFromPercentColumns = std::max(m_scaledWidthFromPercentColumns, LayoutUnit(std::min<float>(maxPercent, tableMaxWidth)));
+ if (m_scaledWidthFromPercentColumns > maxWidth && shouldScaleColumnsForParent(*m_table))
+ maxWidth = m_scaledWidthFromPercentColumns;
}
- maxWidth = std::max<int>(maxWidth, spanMaxLogicalWidth);
+ maxWidth = std::max(maxWidth, LayoutUnit(spanMaxLogicalWidth));
}
void AutoTableLayout::applyPreferredLogicalWidthQuirks(LayoutUnit& minWidth, LayoutUnit& maxWidth) const
{
Length tableLogicalWidth = m_table->style().logicalWidth();
if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive())
- minWidth = maxWidth = std::max<int>(minWidth, tableLogicalWidth.value());
+ minWidth = maxWidth = std::max(minWidth, LayoutUnit(tableLogicalWidth.value()));
}
/*
This method takes care of colspans.
effWidth is the same as width for cells without colspans. If we have colspans, they get modified.
*/
-int AutoTableLayout::calcEffectiveLogicalWidth()
+float AutoTableLayout::calcEffectiveLogicalWidth()
{
- int maxLogicalWidth = 0;
+ float maxLogicalWidth = 0;
size_t nEffCols = m_layoutStruct.size();
- int spacingInRowDirection = m_table->hBorderSpacing();
+ float spacingInRowDirection = m_table->hBorderSpacing();
for (size_t i = 0; i < nEffCols; ++i) {
m_layoutStruct[i].effectiveLogicalWidth = m_layoutStruct[i].logicalWidth;
@@ -285,16 +308,16 @@ int AutoTableLayout::calcEffectiveLogicalWidth()
unsigned effCol = m_table->colToEffCol(cell->col());
size_t lastCol = effCol;
- int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRowDirection;
- int cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRowDirection;
+ float cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRowDirection;
+ float cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRowDirection;
float totalPercent = 0;
- int spanMinLogicalWidth = 0;
- int spanMaxLogicalWidth = 0;
+ float spanMinLogicalWidth = 0;
+ float spanMaxLogicalWidth = 0;
bool allColsArePercent = true;
bool allColsAreFixed = true;
bool haveAuto = false;
bool spanHasEmptyCellsOnly = true;
- int fixedWidth = 0;
+ float fixedWidth = 0;
while (lastCol < nEffCols && span > 0) {
Layout& columnLayout = m_layoutStruct[lastCol];
switch (columnLayout.logicalWidth.type()) {
@@ -345,19 +368,19 @@ int AutoTableLayout::calcEffectiveLogicalWidth()
// can't satify this condition, treat as variable
cellLogicalWidth = Length();
} else {
- maxLogicalWidth = std::max(maxLogicalWidth, static_cast<int>(std::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percent()));
+ maxLogicalWidth = std::max(maxLogicalWidth, std::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percent());
// all non percent columns in the span get percent values to sum up correctly.
float percentMissing = cellLogicalWidth.percent() - totalPercent;
- int totalWidth = 0;
+ float totalWidth = 0;
for (unsigned pos = effCol; pos < lastCol; ++pos) {
- if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent())
+ if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercentOrCalculated())
totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWidth;
}
for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++pos) {
- if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) {
- float percent = percentMissing * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / totalWidth;
+ if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercentOrCalculated()) {
+ float percent = percentMissing * m_layoutStruct[pos].effectiveMaxLogicalWidth / totalWidth;
totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
percentMissing -= percent;
if (percent > 0)
@@ -373,38 +396,38 @@ int AutoTableLayout::calcEffectiveLogicalWidth()
if (cellMinLogicalWidth > spanMinLogicalWidth) {
if (allColsAreFixed) {
for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++pos) {
- int cellLogicalWidth = std::max(m_layoutStruct[pos].effectiveMinLogicalWidth, static_cast<int>(cellMinLogicalWidth * m_layoutStruct[pos].logicalWidth.value() / fixedWidth));
+ float cellLogicalWidth = std::max(m_layoutStruct[pos].effectiveMinLogicalWidth, cellMinLogicalWidth * m_layoutStruct[pos].logicalWidth.value() / fixedWidth);
fixedWidth -= m_layoutStruct[pos].logicalWidth.value();
cellMinLogicalWidth -= cellLogicalWidth;
m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWidth;
}
} else if (allColsArePercent) {
// In this case, we just split the colspan's min amd max widths following the percentage.
- int allocatedMinLogicalWidth = 0;
- int allocatedMaxLogicalWidth = 0;
+ float allocatedMinLogicalWidth = 0;
+ float allocatedMaxLogicalWidth = 0;
for (unsigned pos = effCol; pos < lastCol; ++pos) {
ASSERT(m_layoutStruct[pos].logicalWidth.isPercent() || m_layoutStruct[pos].effectiveLogicalWidth.isPercent());
// |allColsArePercent| means that either the logicalWidth *or* the effectiveLogicalWidth are percents, handle both of them here.
float percent = m_layoutStruct[pos].logicalWidth.isPercent() ? m_layoutStruct[pos].logicalWidth.percent() : m_layoutStruct[pos].effectiveLogicalWidth.percent();
- int columnMinLogicalWidth = static_cast<int>(percent * cellMinLogicalWidth / totalPercent);
- int columnMaxLogicalWidth = static_cast<int>(percent * cellMaxLogicalWidth / totalPercent);
+ float columnMinLogicalWidth = percent * cellMinLogicalWidth / totalPercent;
+ float columnMaxLogicalWidth = percent * cellMaxLogicalWidth / totalPercent;
m_layoutStruct[pos].effectiveMinLogicalWidth = std::max(m_layoutStruct[pos].effectiveMinLogicalWidth, columnMinLogicalWidth);
m_layoutStruct[pos].effectiveMaxLogicalWidth = columnMaxLogicalWidth;
allocatedMinLogicalWidth += columnMinLogicalWidth;
allocatedMaxLogicalWidth += columnMaxLogicalWidth;
}
- ASSERT(allocatedMinLogicalWidth <= cellMinLogicalWidth);
- ASSERT(allocatedMaxLogicalWidth <= cellMaxLogicalWidth);
+ ASSERT(allocatedMinLogicalWidth < cellMinLogicalWidth || WTF::areEssentiallyEqual(allocatedMinLogicalWidth, cellMinLogicalWidth));
+ ASSERT(allocatedMaxLogicalWidth < cellMaxLogicalWidth || WTF::areEssentiallyEqual(allocatedMaxLogicalWidth, cellMaxLogicalWidth));
cellMinLogicalWidth -= allocatedMinLogicalWidth;
cellMaxLogicalWidth -= allocatedMaxLogicalWidth;
} else {
- int remainingMaxLogicalWidth = spanMaxLogicalWidth;
- int remainingMinLogicalWidth = spanMinLogicalWidth;
+ float remainingMaxLogicalWidth = spanMaxLogicalWidth;
+ float remainingMinLogicalWidth = spanMinLogicalWidth;
// Give min to variable first, to fixed second, and to others third.
for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol; ++pos) {
if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth) {
- int colMinLogicalWidth = std::max<int>(m_layoutStruct[pos].effectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value());
+ float colMinLogicalWidth = std::max(m_layoutStruct[pos].effectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value());
fixedWidth -= m_layoutStruct[pos].logicalWidth.value();
remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth;
remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
@@ -415,8 +438,8 @@ int AutoTableLayout::calcEffectiveLogicalWidth()
for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) {
if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth)) {
- int colMinLogicalWidth = std::max<int>(m_layoutStruct[pos].effectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMinLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / remainingMaxLogicalWidth : cellMinLogicalWidth));
- colMinLogicalWidth = std::min<int>(m_layoutStruct[pos].effectiveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colMinLogicalWidth);
+ float colMinLogicalWidth = std::max(m_layoutStruct[pos].effectiveMinLogicalWidth, remainingMaxLogicalWidth ? cellMinLogicalWidth * m_layoutStruct[pos].effectiveMaxLogicalWidth / remainingMaxLogicalWidth : cellMinLogicalWidth);
+ colMinLogicalWidth = std::min(m_layoutStruct[pos].effectiveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colMinLogicalWidth);
remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth;
cellMinLogicalWidth -= colMinLogicalWidth;
@@ -425,10 +448,10 @@ int AutoTableLayout::calcEffectiveLogicalWidth()
}
}
}
- if (!cellLogicalWidth.isPercent()) {
+ if (!cellLogicalWidth.isPercentOrCalculated()) {
if (cellMaxLogicalWidth > spanMaxLogicalWidth) {
for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < lastCol; ++pos) {
- int colMaxLogicalWidth = std::max(m_layoutStruct[pos].effectiveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogicalWidth : cellMaxLogicalWidth));
+ float colMaxLogicalWidth = std::max(m_layoutStruct[pos].effectiveMaxLogicalWidth, spanMaxLogicalWidth ? cellMaxLogicalWidth * m_layoutStruct[pos].effectiveMaxLogicalWidth / spanMaxLogicalWidth : cellMaxLogicalWidth);
spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
cellMaxLogicalWidth -= colMaxLogicalWidth;
m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogicalWidth;
@@ -446,7 +469,7 @@ int AutoTableLayout::calcEffectiveLogicalWidth()
}
m_effectiveLogicalWidthDirty = false;
- return std::min(maxLogicalWidth, INT_MAX / 2);
+ return std::min<float>(maxLogicalWidth, tableMaxWidth);
}
/* gets all cells that originate in a column and have a cellspan > 1
@@ -479,8 +502,8 @@ void AutoTableLayout::insertSpanCell(RenderTableCell *cell)
void AutoTableLayout::layout()
{
// table layout based on the values collected in the layout structure.
- int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection();
- int available = tableLogicalWidth;
+ float tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection();
+ float available = tableLogicalWidth;
size_t nEffCols = m_table->numEffCols();
// FIXME: It is possible to be called without having properly updated our internal representation.
@@ -495,18 +518,18 @@ void AutoTableLayout::layout()
calcEffectiveLogicalWidth();
bool havePercent = false;
- int totalRelative = 0;
+ float totalRelative = 0;
int numAuto = 0;
int numFixed = 0;
float totalAuto = 0;
float totalFixed = 0;
float totalPercent = 0;
- int allocAuto = 0;
+ float allocAuto = 0;
unsigned numAutoEmptyCellsOnly = 0;
// fill up every cell with its minWidth
for (size_t i = 0; i < nEffCols; ++i) {
- int cellLogicalWidth = m_layoutStruct[i].effectiveMinLogicalWidth;
+ float cellLogicalWidth = m_layoutStruct[i].effectiveMinLogicalWidth;
m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
available -= cellLogicalWidth;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
@@ -540,23 +563,23 @@ void AutoTableLayout::layout()
if (available > 0 && havePercent) {
for (size_t i = 0; i < nEffCols; ++i) {
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
- if (logicalWidth.isPercent()) {
- int cellLogicalWidth = std::max<int>(m_layoutStruct[i].effectiveMinLogicalWidth, minimumValueForLength(logicalWidth, tableLogicalWidth));
+ if (logicalWidth.isPercentOrCalculated()) {
+ float cellLogicalWidth = std::max<float>(m_layoutStruct[i].effectiveMinLogicalWidth, minimumValueForLength(logicalWidth, tableLogicalWidth));
available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth;
m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
}
}
if (totalPercent > 100) {
// remove overallocated space from the last columns
- int excess = tableLogicalWidth * (totalPercent - 100) / 100;
+ float excess = tableLogicalWidth * (totalPercent - 100) / 100;
for (unsigned i = nEffCols; i; ) {
--i;
- if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) {
- int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidth;
- int reduction = std::min(cellLogicalWidth, excess);
+ if (m_layoutStruct[i].effectiveLogicalWidth.isPercentOrCalculated()) {
+ float cellLogicalWidth = m_layoutStruct[i].computedLogicalWidth;
+ float reduction = std::min(cellLogicalWidth, excess);
// the lines below might look inconsistent, but that's the way it's handled in mozilla
excess -= reduction;
- int newLogicalWidth = std::max<int>(m_layoutStruct[i].effectiveMinLogicalWidth, cellLogicalWidth - reduction);
+ float newLogicalWidth = std::max(m_layoutStruct[i].effectiveMinLogicalWidth, cellLogicalWidth - reduction);
available += cellLogicalWidth - newLogicalWidth;
m_layoutStruct[i].computedLogicalWidth = newLogicalWidth;
}
@@ -581,7 +604,7 @@ void AutoTableLayout::layout()
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
if (logicalWidth.isRelative() && logicalWidth.value() != 0) {
// width=0* gets effMinWidth.
- int cellLogicalWidth = logicalWidth.value() * tableLogicalWidth / totalRelative;
+ float cellLogicalWidth = logicalWidth.value() * tableLogicalWidth / totalRelative;
available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth;
m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
}
@@ -594,7 +617,7 @@ void AutoTableLayout::layout()
for (size_t i = 0; i < nEffCols; ++i) {
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCellsOnly) {
- int cellLogicalWidth = std::max<int>(m_layoutStruct[i].computedLogicalWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalAuto));
+ float cellLogicalWidth = std::max(m_layoutStruct[i].computedLogicalWidth, available * m_layoutStruct[i].effectiveMaxLogicalWidth / totalAuto);
available -= cellLogicalWidth;
totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth;
m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
@@ -607,7 +630,7 @@ void AutoTableLayout::layout()
for (size_t i = 0; i < nEffCols; ++i) {
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
if (logicalWidth.isFixed()) {
- int cellLogicalWidth = static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalFixed);
+ float cellLogicalWidth = available * m_layoutStruct[i].effectiveMaxLogicalWidth / totalFixed;
available -= cellLogicalWidth;
totalFixed -= m_layoutStruct[i].effectiveMaxLogicalWidth;
m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
@@ -620,7 +643,7 @@ void AutoTableLayout::layout()
for (size_t i = 0; i < nEffCols; ++i) {
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
if (logicalWidth.isPercent()) {
- int cellLogicalWidth = available * logicalWidth.percent() / totalPercent;
+ float cellLogicalWidth = available * logicalWidth.percent() / totalPercent;
available -= cellLogicalWidth;
totalPercent -= logicalWidth.percent();
m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
@@ -639,7 +662,7 @@ void AutoTableLayout::layout()
// variable columns with empty cells only don't get any width
if (m_layoutStruct[i].effectiveLogicalWidth.isAuto() && m_layoutStruct[i].emptyCellsOnly)
continue;
- int cellLogicalWidth = available / total;
+ float cellLogicalWidth = available / total;
available -= cellLogicalWidth;
total--;
m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
@@ -647,7 +670,7 @@ void AutoTableLayout::layout()
}
// If we have overallocated, reduce every cell according to the difference between desired width and minwidth
- // this seems to produce to the pixel exact results with IE. Wonder is some of this also holds for width distributing.
+ // this seems to produce to the pixel exact results with IE. Wonder if some of this also holds for width distributing.
if (available < 0) {
// Need to reduce cells with the following prioritization:
// (1) Auto
@@ -656,7 +679,7 @@ void AutoTableLayout::layout()
// (4) Percent
// This is basically the reverse of how we grew the cells.
if (available < 0) {
- int logicalWidthBeyondMin = 0;
+ float logicalWidthBeyondMin = 0;
for (unsigned i = nEffCols; i; ) {
--i;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
@@ -668,8 +691,8 @@ void AutoTableLayout::layout()
--i;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
if (logicalWidth.isAuto()) {
- int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
- int reduce = available * minMaxDiff / logicalWidthBeyondMin;
+ float minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
+ float reduce = available * minMaxDiff / logicalWidthBeyondMin;
m_layoutStruct[i].computedLogicalWidth += reduce;
available -= reduce;
logicalWidthBeyondMin -= minMaxDiff;
@@ -680,7 +703,7 @@ void AutoTableLayout::layout()
}
if (available < 0) {
- int logicalWidthBeyondMin = 0;
+ float logicalWidthBeyondMin = 0;
for (unsigned i = nEffCols; i; ) {
--i;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
@@ -692,8 +715,8 @@ void AutoTableLayout::layout()
--i;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
if (logicalWidth.isRelative()) {
- int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
- int reduce = available * minMaxDiff / logicalWidthBeyondMin;
+ float minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
+ float reduce = available * minMaxDiff / logicalWidthBeyondMin;
m_layoutStruct[i].computedLogicalWidth += reduce;
available -= reduce;
logicalWidthBeyondMin -= minMaxDiff;
@@ -704,7 +727,7 @@ void AutoTableLayout::layout()
}
if (available < 0) {
- int logicalWidthBeyondMin = 0;
+ float logicalWidthBeyondMin = 0;
for (unsigned i = nEffCols; i; ) {
--i;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
@@ -716,8 +739,8 @@ void AutoTableLayout::layout()
--i;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
if (logicalWidth.isFixed()) {
- int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
- int reduce = available * minMaxDiff / logicalWidthBeyondMin;
+ float minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
+ float reduce = available * minMaxDiff / logicalWidthBeyondMin;
m_layoutStruct[i].computedLogicalWidth += reduce;
available -= reduce;
logicalWidthBeyondMin -= minMaxDiff;
@@ -728,20 +751,20 @@ void AutoTableLayout::layout()
}
if (available < 0) {
- int logicalWidthBeyondMin = 0;
+ float logicalWidthBeyondMin = 0;
for (unsigned i = nEffCols; i; ) {
--i;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
- if (logicalWidth.isPercent())
+ if (logicalWidth.isPercentOrCalculated())
logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
}
for (unsigned i = nEffCols; i && logicalWidthBeyondMin > 0; ) {
--i;
Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
- if (logicalWidth.isPercent()) {
- int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
- int reduce = available * minMaxDiff / logicalWidthBeyondMin;
+ if (logicalWidth.isPercentOrCalculated()) {
+ float minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
+ float reduce = available * minMaxDiff / logicalWidthBeyondMin;
m_layoutStruct[i].computedLogicalWidth += reduce;
available -= reduce;
logicalWidthBeyondMin -= minMaxDiff;
@@ -752,10 +775,10 @@ void AutoTableLayout::layout()
}
}
- int pos = 0;
+ LayoutUnit pos = 0;
for (size_t i = 0; i < nEffCols; ++i) {
m_table->setColumnPosition(i, pos);
- pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing();
+ pos += LayoutUnit::fromFloatCeil(m_layoutStruct[i].computedLogicalWidth) + m_table->hBorderSpacing();
}
m_table->setColumnPosition(m_table->columnPositions().size() - 1, pos);
}