AutoTableLayout.cpp [plain text]
#include "config.h"
#include "AutoTableLayout.h"
#include "RenderTable.h"
#include "RenderTableCell.h"
#include "RenderTableCol.h"
#include "RenderTableSection.h"
using namespace std;
namespace WebCore {
AutoTableLayout::AutoTableLayout(RenderTable* table)
: TableLayout(table)
, m_hasPercent(false)
, m_percentagesDirty(true)
, m_effWidthDirty(true)
, m_totalPercent(0)
{
}
AutoTableLayout::~AutoTableLayout()
{
}
void AutoTableLayout::recalcColumn(int effCol)
{
Layout &l = m_layoutStruct[effCol];
RenderObject* child = m_table->firstChild();
RenderTableCell* fixedContributor = 0;
RenderTableCell* maxContributor = 0;
while (child) {
if (child->isTableSection()) {
RenderTableSection* section = static_cast<RenderTableSection*>(child);
int numRows = section->numRows();
RenderTableCell* last = 0;
for (int i = 0; i < numRows; i++) {
RenderTableSection::CellStruct current = section->cellAt(i, effCol);
RenderTableCell* cell = current.cell;
if (current.inColSpan)
continue;
if (cell && cell->colSpan() == 1) {
l.minWidth = max(l.minWidth, 1);
l.maxWidth = max(l.maxWidth, 1);
if (!cell->minMaxKnown())
cell->calcMinMaxWidth();
if (cell->minWidth() > l.minWidth)
l.minWidth = cell->minWidth();
if (cell->maxWidth() > l.maxWidth) {
l.maxWidth = cell->maxWidth();
maxContributor = cell;
}
Length w = cell->styleOrColWidth();
if (w.value() > 32760)
w.setValue(32760);
if (w.value() < 0)
w.setValue(0);
switch(w.type()) {
case Fixed:
if (w.value() > 0 && (int)l.width.type() != Percent) {
int wval = cell->calcBorderBoxWidth(w.value());
if (l.width.isFixed()) {
if ((wval > l.width.value()) ||
((l.width.value() == wval) && (maxContributor == cell))) {
l.width.setValue(wval);
fixedContributor = cell;
}
} else {
l.width.setValue(Fixed, wval);
fixedContributor = cell;
}
}
break;
case Percent:
m_hasPercent = true;
if (w.value() > 0 && (!l.width.isPercent() || w.value() > l.width.value()))
l.width = w;
break;
case Relative:
if (w.isAuto() || (w.isRelative() && w.value() > l.width.value()))
l.width = w;
default:
break;
}
} else {
if (cell && (!effCol || section->cellAt(i, effCol-1).cell != cell)) {
l.minWidth = max(l.minWidth, 1);
l.maxWidth = max(l.maxWidth, 1);
insertSpanCell(cell);
}
last = cell;
}
}
}
child = child->nextSibling();
}
if (l.width.isFixed()) {
if (m_table->style()->htmlHacks() && l.maxWidth > l.width.value() && fixedContributor != maxContributor) {
l.width = Length();
fixedContributor = 0;
}
}
l.maxWidth = max(l.maxWidth, l.minWidth);
#ifdef DEBUG_LAYOUT
qDebug("col %d, final min=%d, max=%d, width=%d(%d)", effCol, l.minWidth, l.maxWidth, l.width.value, l.width.type);
#endif
}
void AutoTableLayout::fullRecalc()
{
m_percentagesDirty = true;
m_hasPercent = false;
m_effWidthDirty = true;
int nEffCols = m_table->numEffCols();
m_layoutStruct.resize(nEffCols);
m_layoutStruct.fill(Layout());
m_spanCells.fill(0);
RenderObject *child = m_table->firstChild();
Length grpWidth;
int cCol = 0;
while (child) {
if (child->isTableCol()) {
RenderTableCol *col = static_cast<RenderTableCol*>(child);
int span = col->span();
if (col->firstChild()) {
grpWidth = col->style()->width();
} else {
Length w = col->style()->width();
if (w.isAuto())
w = grpWidth;
if ((w.isFixed() && w.value() == 0) || (w.isPercent() && w.value() == 0))
w = Length();
int cEffCol = m_table->colToEffCol(cCol);
#ifdef DEBUG_LAYOUT
qDebug(" col element %d (eff=%d): Length=%d(%d), span=%d, effColSpan=%d", cCol, cEffCol, w.value, w.type, span, m_table->spanOfEffCol(cEffCol));
#endif
if (!w.isAuto() && span == 1 && cEffCol < nEffCols) {
if (m_table->spanOfEffCol(cEffCol) == 1) {
m_layoutStruct[cEffCol].width = w;
if (w.isFixed() && m_layoutStruct[cEffCol].maxWidth < w.value())
m_layoutStruct[cEffCol].maxWidth = w.value();
}
}
cCol += span;
}
} else {
break;
}
RenderObject *next = child->firstChild();
if (!next)
next = child->nextSibling();
if (!next && child->parent()->isTableCol()) {
next = child->parent()->nextSibling();
grpWidth = Length();
}
child = next;
}
for (int i = 0; i < nEffCols; i++)
recalcColumn(i);
}
static bool shouldScaleColumns(RenderTable* table)
{
bool scale = true;
while (table) {
Length tw = table->style()->width();
if ((tw.isAuto() || tw.isPercent()) && !table->isPositioned()) {
RenderBlock* cb = table->containingBlock();
while (cb && !cb->isRenderView() && !cb->isTableCell() &&
cb->style()->width().isAuto() && !cb->isPositioned())
cb = cb->containingBlock();
table = 0;
if (cb && cb->isTableCell() &&
(cb->style()->width().isAuto() || cb->style()->width().isPercent())) {
if (tw.isPercent())
scale = false;
else {
RenderTableCell* cell = static_cast<RenderTableCell*>(cb);
if (cell->colSpan() > 1 || cell->table()->style()->width().isAuto())
scale = false;
else
table = cell->table();
}
}
}
else
table = 0;
}
return scale;
}
void AutoTableLayout::calcMinMaxWidth()
{
#ifdef DEBUG_LAYOUT
qDebug("AutoTableLayout::calcMinMaxWidth");
#endif
fullRecalc();
int spanMaxWidth = calcEffectiveWidth();
int minWidth = 0;
int maxWidth = 0;
int maxPercent = 0;
int maxNonPercent = 0;
int remainingPercent = 100;
for (unsigned int i = 0; i < m_layoutStruct.size(); i++) {
minWidth += m_layoutStruct[i].effMinWidth;
maxWidth += m_layoutStruct[i].effMaxWidth;
if (m_layoutStruct[i].effWidth.isPercent()) {
int percent = min(m_layoutStruct[i].effWidth.value(), remainingPercent);
int pw = (m_layoutStruct[i].effMaxWidth * 100) / max(percent, 1);
remainingPercent -= percent;
maxPercent = max(pw, maxPercent);
} else {
maxNonPercent += m_layoutStruct[i].effMaxWidth;
}
}
if (shouldScaleColumns(m_table)) {
maxNonPercent = (maxNonPercent * 100 + 50) / max(remainingPercent, 1);
maxWidth = max(maxNonPercent, maxWidth);
maxWidth = max(maxWidth, maxPercent);
}
maxWidth = max(maxWidth, spanMaxWidth);
int bs = m_table->bordersPaddingAndSpacing();
minWidth += bs;
maxWidth += bs;
Length tw = m_table->style()->width();
if (tw.isFixed() && tw.value() > 0) {
minWidth = max(minWidth, tw.value());
maxWidth = minWidth;
}
m_table->m_maxWidth = maxWidth;
m_table->m_minWidth = minWidth;
#ifdef DEBUG_LAYOUT
qDebug(" minWidth=%d, maxWidth=%d", m_table->m_minWidth, m_table->m_maxWidth);
#endif
}
int AutoTableLayout::calcEffectiveWidth()
{
int tMaxWidth = 0;
unsigned int nEffCols = m_layoutStruct.size();
int hspacing = m_table->hBorderSpacing();
#ifdef DEBUG_LAYOUT
qDebug("AutoTableLayout::calcEffectiveWidth for %d cols", nEffCols);
#endif
for (unsigned int i = 0; i < nEffCols; i++) {
m_layoutStruct[i].effWidth = m_layoutStruct[i].width;
m_layoutStruct[i].effMinWidth = m_layoutStruct[i].minWidth;
m_layoutStruct[i].effMaxWidth = m_layoutStruct[i].maxWidth;
}
for (unsigned int i = 0; i < m_spanCells.size(); i++) {
RenderTableCell *cell = m_spanCells[i];
if (!cell)
break;
int span = cell->colSpan();
Length w = cell->styleOrColWidth();
if (!w.isRelative() && w.value() == 0)
w = Length();
int col = m_table->colToEffCol(cell->col());
unsigned int lastCol = col;
int cMinWidth = cell->minWidth() + hspacing;
int cMaxWidth = cell->maxWidth() + hspacing;
int totalPercent = 0;
int minWidth = 0;
int maxWidth = 0;
bool allColsArePercent = true;
bool allColsAreFixed = true;
bool haveAuto = false;
int fixedWidth = 0;
#ifdef DEBUG_LAYOUT
int cSpan = span;
#endif
while (lastCol < nEffCols && span > 0) {
switch (m_layoutStruct[lastCol].width.type()) {
case Percent:
totalPercent += m_layoutStruct[lastCol].width.value();
allColsAreFixed = false;
break;
case Fixed:
if (m_layoutStruct[lastCol].width.value() > 0) {
fixedWidth += m_layoutStruct[lastCol].width.value();
allColsArePercent = false;
break;
}
case Auto:
haveAuto = true;
default:
if (!m_layoutStruct[lastCol].effWidth.isPercent()) {
m_layoutStruct[lastCol].effWidth = Length();
allColsArePercent = false;
}
else
totalPercent += m_layoutStruct[lastCol].effWidth.value();
allColsAreFixed = false;
}
span -= m_table->spanOfEffCol(lastCol);
minWidth += m_layoutStruct[lastCol].effMinWidth;
maxWidth += m_layoutStruct[lastCol].effMaxWidth;
lastCol++;
cMinWidth -= hspacing;
cMaxWidth -= hspacing;
}
#ifdef DEBUG_LAYOUT
qDebug(" colspan cell %p at effCol %d, span %d, type %d, value %d cmin=%d min=%d fixedwidth=%d", cell, col, cSpan, w.type, w.value, cMinWidth, minWidth, fixedWidth);
#endif
if (w.isPercent()) {
if (totalPercent > w.value() || allColsArePercent) {
w = Length();
} else {
int spanMax = max(maxWidth, cMaxWidth);
#ifdef DEBUG_LAYOUT
qDebug(" adjusting tMaxWidth (%d): spanMax=%d, value=%d, totalPercent=%d", tMaxWidth, spanMax, w.value, totalPercent);
#endif
tMaxWidth = max(tMaxWidth, spanMax * 100 / w.value());
int percentMissing = w.value() - totalPercent;
int totalWidth = 0;
for (unsigned int pos = col; pos < lastCol; pos++) {
if (!(m_layoutStruct[pos].width.isPercent()))
totalWidth += m_layoutStruct[pos].effMaxWidth;
}
for (unsigned int pos = col; pos < lastCol && totalWidth > 0; pos++) {
if (!(m_layoutStruct[pos].width.isPercent())) {
int percent = percentMissing * m_layoutStruct[pos].effMaxWidth / totalWidth;
#ifdef DEBUG_LAYOUT
qDebug(" col %d: setting percent value %d effMaxWidth=%d totalWidth=%d", pos, percent, m_layoutStruct[pos].effMaxWidth, totalWidth);
#endif
totalWidth -= m_layoutStruct[pos].effMaxWidth;
percentMissing -= percent;
if (percent > 0)
m_layoutStruct[pos].effWidth = Length(percent, Percent);
else
m_layoutStruct[pos].effWidth = Length();
}
}
}
}
if (cMinWidth > minWidth) {
if (allColsAreFixed) {
#ifdef DEBUG_LAYOUT
qDebug("extending minWidth of cols %d-%d to %dpx currentMin=%d accroding to fixed sum %d", col, lastCol-1, cMinWidth, minWidth, fixedWidth);
#endif
for (unsigned int pos = col; fixedWidth > 0 && pos < lastCol; pos++) {
int w = max(m_layoutStruct[pos].effMinWidth, cMinWidth * m_layoutStruct[pos].width.value() / fixedWidth);
#ifdef DEBUG_LAYOUT
qDebug(" col %d: min=%d, effMin=%d, new=%d", pos, m_layoutStruct[pos].effMinWidth, m_layoutStruct[pos].effMinWidth, w);
#endif
fixedWidth -= m_layoutStruct[pos].width.value();
cMinWidth -= w;
m_layoutStruct[pos].effMinWidth = w;
}
} else {
#ifdef DEBUG_LAYOUT
qDebug("extending minWidth of cols %d-%d to %dpx currentMin=%d", col, lastCol-1, cMinWidth, minWidth);
#endif
int maxw = maxWidth;
int minw = minWidth;
for (unsigned int pos = col; maxw >= 0 && pos < lastCol; pos++) {
if (m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth) {
int w = max(m_layoutStruct[pos].effMinWidth, m_layoutStruct[pos].width.value());
fixedWidth -= m_layoutStruct[pos].width.value();
minw -= m_layoutStruct[pos].effMinWidth;
#ifdef DEBUG_LAYOUT
qDebug(" col %d: min=%d, effMin=%d, new=%d", pos, m_layoutStruct[pos].effMinWidth, m_layoutStruct[pos].effMinWidth, w);
#endif
maxw -= m_layoutStruct[pos].effMaxWidth;
cMinWidth -= w;
m_layoutStruct[pos].effMinWidth = w;
}
}
for (unsigned int pos = col; maxw >= 0 && pos < lastCol && minw < cMinWidth; pos++) {
if (!(m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth)) {
int w = max(m_layoutStruct[pos].effMinWidth, maxw ? (cMinWidth * m_layoutStruct[pos].effMaxWidth / maxw) : cMinWidth);
w = min(m_layoutStruct[pos].effMinWidth+(cMinWidth-minw), w);
#ifdef DEBUG_LAYOUT
qDebug(" col %d: min=%d, effMin=%d, new=%d", pos, m_layoutStruct[pos].effMinWidth, m_layoutStruct[pos].effMinWidth, w);
#endif
maxw -= m_layoutStruct[pos].effMaxWidth;
minw -= m_layoutStruct[pos].effMinWidth;
cMinWidth -= w;
m_layoutStruct[pos].effMinWidth = w;
}
}
}
}
if (!(w.isPercent())) {
if (cMaxWidth > maxWidth) {
#ifdef DEBUG_LAYOUT
qDebug("extending maxWidth of cols %d-%d to %dpx", col, lastCol-1, cMaxWidth);
#endif
for (unsigned int pos = col; maxWidth >= 0 && pos < lastCol; pos++) {
int w = max(m_layoutStruct[pos].effMaxWidth, maxWidth ? (cMaxWidth * m_layoutStruct[pos].effMaxWidth / maxWidth) : cMaxWidth);
#ifdef DEBUG_LAYOUT
qDebug(" col %d: max=%d, effMax=%d, new=%d", pos, m_layoutStruct[pos].effMaxWidth, m_layoutStruct[pos].effMaxWidth, w);
#endif
maxWidth -= m_layoutStruct[pos].effMaxWidth;
cMaxWidth -= w;
m_layoutStruct[pos].effMaxWidth = w;
}
}
} else {
for (unsigned int pos = col; pos < lastCol; pos++)
m_layoutStruct[pos].maxWidth = max(m_layoutStruct[pos].maxWidth, m_layoutStruct[pos].minWidth);
}
}
m_effWidthDirty = false;
return tMaxWidth;
}
void AutoTableLayout::insertSpanCell(RenderTableCell *cell)
{
if (!cell || cell->colSpan() == 1)
return;
int size = m_spanCells.size();
if (!size || m_spanCells[size-1] != 0) {
m_spanCells.resize(size + 10);
for (int i = 0; i < 10; i++)
m_spanCells[size+i] = 0;
size += 10;
}
unsigned int pos = 0;
int span = cell->colSpan();
while (pos < m_spanCells.size() && m_spanCells[pos] && span > m_spanCells[pos]->colSpan())
pos++;
memmove(m_spanCells.data()+pos+1, m_spanCells.data()+pos, (size-pos-1)*sizeof(RenderTableCell *));
m_spanCells[pos] = cell;
}
void AutoTableLayout::layout()
{
int tableWidth = m_table->width() - m_table->bordersPaddingAndSpacing();
int available = tableWidth;
int nEffCols = m_table->numEffCols();
if (nEffCols != (int)m_layoutStruct.size()) {
fullRecalc();
nEffCols = m_table->numEffCols();
}
#ifdef DEBUG_LAYOUT
qDebug("AutoTableLayout::layout()");
#endif
if (m_effWidthDirty)
calcEffectiveWidth();
#ifdef DEBUG_LAYOUT
qDebug(" tableWidth=%d, nEffCols=%d", tableWidth, nEffCols);
for (int i = 0; i < nEffCols; i++) {
qDebug(" effcol %d is of type %d value %d, minWidth=%d, maxWidth=%d",
i, m_layoutStruct[i].width.type, m_layoutStruct[i].width.value,
m_layoutStruct[i].minWidth, m_layoutStruct[i].maxWidth);
qDebug(" effective: type %d value %d, minWidth=%d, maxWidth=%d",
m_layoutStruct[i].effWidth.type, m_layoutStruct[i].effWidth.value,
m_layoutStruct[i].effMinWidth, m_layoutStruct[i].effMaxWidth);
}
#endif
bool havePercent = false;
bool haveRelative = false;
int totalRelative = 0;
int numAuto = 0;
int numFixed = 0;
int totalAuto = 0;
int totalFixed = 0;
int totalPercent = 0;
int allocAuto = 0;
for (int i = 0; i < nEffCols; i++) {
int w = m_layoutStruct[i].effMinWidth;
m_layoutStruct[i].calcWidth = w;
available -= w;
Length& width = m_layoutStruct[i].effWidth;
switch (width.type()) {
case Percent:
havePercent = true;
totalPercent += width.value();
break;
case Relative:
haveRelative = true;
totalRelative += width.value();
break;
case Fixed:
numFixed++;
totalFixed += m_layoutStruct[i].effMaxWidth;
break;
case Auto:
case Static:
numAuto++;
totalAuto += m_layoutStruct[i].effMaxWidth;
allocAuto += w;
default:
break;
}
}
if (available > 0 && havePercent) {
for (int i = 0; i < nEffCols; i++) {
Length &width = m_layoutStruct[i].effWidth;
if (width.isPercent()) {
int w = max(int(m_layoutStruct[i].effMinWidth), width.calcMinValue(tableWidth));
available += m_layoutStruct[i].calcWidth - w;
m_layoutStruct[i].calcWidth = w;
}
}
if (totalPercent > 100) {
int excess = tableWidth*(totalPercent-100)/100;
for (int i = nEffCols-1; i >= 0; i--) {
if (m_layoutStruct[i].effWidth.isPercent()) {
int w = m_layoutStruct[i].calcWidth;
int reduction = min(w, excess);
excess -= reduction;
int newWidth = max(int (m_layoutStruct[i].effMinWidth), w - reduction);
available += w - newWidth;
m_layoutStruct[i].calcWidth = newWidth;
}
}
}
}
#ifdef DEBUG_LAYOUT
qDebug("percent satisfied: available is %d", available);
#endif
if (available > 0) {
for (int i = 0; i < nEffCols; ++i) {
Length &width = m_layoutStruct[i].effWidth;
if (width.isFixed() && width.value() > m_layoutStruct[i].calcWidth) {
available += m_layoutStruct[i].calcWidth - width.value();
m_layoutStruct[i].calcWidth = width.value();
}
}
}
#ifdef DEBUG_LAYOUT
qDebug("fixed satisfied: available is %d", available);
#endif
if (available > 0) {
for (int i = 0; i < nEffCols; i++) {
Length &width = m_layoutStruct[i].effWidth;
if (width.isRelative() && width.value() != 0) {
int w = width.value() * tableWidth / totalRelative;
available += m_layoutStruct[i].calcWidth - w;
m_layoutStruct[i].calcWidth = w;
}
}
}
if (available > 0 && numAuto) {
available += allocAuto; for (int i = 0; i < nEffCols; i++) {
Length &width = m_layoutStruct[i].effWidth;
if (width.isAuto() && totalAuto != 0) {
int w = max(int(m_layoutStruct[i].calcWidth), available * m_layoutStruct[i].effMaxWidth / totalAuto);
available -= w;
totalAuto -= m_layoutStruct[i].effMaxWidth;
m_layoutStruct[i].calcWidth = w;
}
}
}
#ifdef DEBUG_LAYOUT
qDebug("variable satisfied: available is %d", available);
#endif
if (available > 0 && numFixed) {
for (int i = 0; i < nEffCols; i++) {
Length &width = m_layoutStruct[i].effWidth;
if (width.isFixed()) {
int w = available * m_layoutStruct[i].effMaxWidth / totalFixed;
available -= w;
totalFixed -= m_layoutStruct[i].effMaxWidth;
m_layoutStruct[i].calcWidth += w;
}
}
}
#ifdef DEBUG_LAYOUT
qDebug("after fixed distribution: available=%d", available);
#endif
if (available > 0 && m_hasPercent && totalPercent < 100) {
for (int i = 0; i < nEffCols; i++) {
Length &width = m_layoutStruct[i].effWidth;
if (width.isPercent()) {
int w = available * width.value() / totalPercent;
available -= w;
totalPercent -= width.value();
m_layoutStruct[i].calcWidth += w;
if (!available || !totalPercent) break;
}
}
}
#ifdef DEBUG_LAYOUT
qDebug("after percent distribution: available=%d", available);
#endif
if (available > 0) {
int total = nEffCols;
int i = nEffCols;
while ( i--) {
int w = available / total;
available -= w;
total--;
m_layoutStruct[i].calcWidth += w;
}
}
#ifdef DEBUG_LAYOUT
qDebug("after equal distribution: available=%d", available);
#endif
if (available < 0) {
if (available < 0) {
int mw = 0;
for (int i = nEffCols-1; i >= 0; i--) {
Length &width = m_layoutStruct[i].effWidth;
if (width.isAuto())
mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;
}
for (int i = nEffCols-1; i >= 0 && mw > 0; i--) {
Length &width = m_layoutStruct[i].effWidth;
if (width.isAuto()) {
int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth;
int reduce = available * minMaxDiff / mw;
m_layoutStruct[i].calcWidth += reduce;
available -= reduce;
mw -= minMaxDiff;
if (available >= 0)
break;
}
}
}
if (available < 0) {
int mw = 0;
for (int i = nEffCols-1; i >= 0; i--) {
Length& width = m_layoutStruct[i].effWidth;
if (width.isRelative())
mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;
}
for (int i = nEffCols-1; i >= 0 && mw > 0; i--) {
Length& width = m_layoutStruct[i].effWidth;
if (width.isRelative()) {
int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth;
int reduce = available * minMaxDiff / mw;
m_layoutStruct[i].calcWidth += reduce;
available -= reduce;
mw -= minMaxDiff;
if (available >= 0)
break;
}
}
}
if (available < 0) {
int mw = 0;
for (int i = nEffCols-1; i >= 0; i--) {
Length& width = m_layoutStruct[i].effWidth;
if (width.isFixed())
mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;
}
for (int i = nEffCols-1; i >= 0 && mw > 0; i--) {
Length& width = m_layoutStruct[i].effWidth;
if (width.isFixed()) {
int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth;
int reduce = available * minMaxDiff / mw;
m_layoutStruct[i].calcWidth += reduce;
available -= reduce;
mw -= minMaxDiff;
if (available >= 0)
break;
}
}
}
if (available < 0) {
int mw = 0;
for (int i = nEffCols-1; i >= 0; i--) {
Length& width = m_layoutStruct[i].effWidth;
if (width.isPercent())
mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;
}
for (int i = nEffCols-1; i >= 0 && mw > 0; i--) {
Length& width = m_layoutStruct[i].effWidth;
if (width.isPercent()) {
int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth;
int reduce = available * minMaxDiff / mw;
m_layoutStruct[i].calcWidth += reduce;
available -= reduce;
mw -= minMaxDiff;
if (available >= 0)
break;
}
}
}
}
int pos = 0;
for (int i = 0; i < nEffCols; i++) {
#ifdef DEBUG_LAYOUT
qDebug("col %d: %d (width %d)", i, pos, m_layoutStruct[i].calcWidth);
#endif
m_table->columnPos[i] = pos;
pos += m_layoutStruct[i].calcWidth + m_table->hBorderSpacing();
}
m_table->columnPos[m_table->columnPos.size()-1] = pos;
}
void AutoTableLayout::calcPercentages() const
{
m_totalPercent = 0;
for (unsigned i = 0; i < m_layoutStruct.size(); i++) {
if (m_layoutStruct[i].width.isPercent())
m_totalPercent += m_layoutStruct[i].width.value();
}
m_percentagesDirty = false;
}
#undef DEBUG_LAYOUT
}