18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2002 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2002 Dirk Mueller (mueller@kde.org)
428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "AutoTableLayout.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTable.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTableCell.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTableCol.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTableSection.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectAutoTableLayout::AutoTableLayout(RenderTable* table)
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : TableLayout(table)
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_hasPercent(false)
3728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    , m_effectiveLogicalWidthDirty(true)
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectAutoTableLayout::~AutoTableLayout()
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid AutoTableLayout::recalcColumn(int effCol)
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    Layout& columnLayout = m_layoutStruct[effCol];
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderTableCell* fixedContributor = 0;
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderTableCell* maxContributor = 0;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    for (RenderObject* child = m_table->firstChild(); child; child = child->nextSibling()) {
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (child->isTableCol())
54bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            toRenderTableCol(child)->computePreferredLogicalWidths();
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        else if (child->isTableSection()) {
560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            RenderTableSection* section = toRenderTableSection(child);
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int numRows = section->numRows();
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int i = 0; i < numRows; i++) {
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                RenderTableSection::CellStruct current = section->cellAt(i, effCol);
600617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen                RenderTableCell* cell = current.primaryCell();
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
620617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen                bool cellHasContent = cell && !current.inColSpan && (cell->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding());
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (cellHasContent)
6428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    columnLayout.emptyCellsOnly = false;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (current.inColSpan || !cell)
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    continue;
6828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
6928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (cell->colSpan() == 1) {
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // A cell originates in this column.  Ensure we have
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // a min/max width of at least 1px for this column now.
7228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    columnLayout.minLogicalWidth = max(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0);
7328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, 1);
74bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                    if (cell->preferredLogicalWidthsDirty())
75bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen                        cell->computePreferredLogicalWidths();
7628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    columnLayout.minLogicalWidth = max(cell->minPreferredLogicalWidth(), columnLayout.minLogicalWidth);
7728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) {
7828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        columnLayout.maxLogicalWidth = cell->maxPreferredLogicalWidth();
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        maxContributor = cell;
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    Length cellLogicalWidth = cell->styleOrColLogicalWidth();
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // FIXME: What is this arbitrary value?
842bde8e466a4451c7319e3a072d118917957d6554Steve Block                    if (cellLogicalWidth.value() > 32760)
852bde8e466a4451c7319e3a072d118917957d6554Steve Block                        cellLogicalWidth.setValue(32760);
8628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    if (cellLogicalWidth.isNegative())
8728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        cellLogicalWidth.setValue(0);
8828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    switch (cellLogicalWidth.type()) {
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case Fixed:
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // ignore width=0
9128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        if (cellLogicalWidth.value() > 0 && columnLayout.logicalWidth.type() != Percent) {
9228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                            int logicalWidth = cell->computeBorderBoxLogicalWidth(cellLogicalWidth.value());
9328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                            if (columnLayout.logicalWidth.isFixed()) {
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                // Nav/IE weirdness
9528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                if ((logicalWidth > columnLayout.logicalWidth.value()) ||
9628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                    ((columnLayout.logicalWidth.value() == logicalWidth) && (maxContributor == cell))) {
9728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                    columnLayout.logicalWidth.setValue(logicalWidth);
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    fixedContributor = cell;
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                }
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            } else {
10128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                                columnLayout.logicalWidth.setValue(Fixed, logicalWidth);
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                fixedContributor = cell;
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            }
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case Percent:
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        m_hasPercent = true;
1082bde8e466a4451c7319e3a072d118917957d6554Steve Block                        if (cellLogicalWidth.isPositive() && (!columnLayout.logicalWidth.isPercent() || cellLogicalWidth.value() > columnLayout.logicalWidth.value()))
10928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                            columnLayout.logicalWidth = cellLogicalWidth;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    case Relative:
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // FIXME: Need to understand this case and whether it makes sense to compare values
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // which are not necessarily of the same type.
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block                        if (cellLogicalWidth.isAuto() || (cellLogicalWidth.isRelative() && cellLogicalWidth.value() > columnLayout.logicalWidth.value()))
11528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                            columnLayout.logicalWidth = cellLogicalWidth;
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    default:
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
11928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) {
12028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    // This spanning cell originates in this column.  Ensure we have
12128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    // a min/max width of at least 1px for this column now.
12228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    columnLayout.minLogicalWidth = max(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0);
12328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, 1);
12428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    insertSpanCell(cell);
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Nav/IE weirdness
13128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (columnLayout.logicalWidth.isFixed()) {
13228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (m_table->document()->inQuirksMode() && columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() && fixedContributor != maxContributor) {
13328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            columnLayout.logicalWidth = Length();
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            fixedContributor = 0;
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, columnLayout.minLogicalWidth);
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid AutoTableLayout::fullRecalc()
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_hasPercent = false;
14428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    m_effectiveLogicalWidthDirty = true;
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int nEffCols = m_table->numEffCols();
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_layoutStruct.resize(nEffCols);
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_layoutStruct.fill(Layout());
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_spanCells.fill(0);
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    RenderObject* child = m_table->firstChild();
15228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    Length groupLogicalWidth;
15328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int currentColumn = 0;
15428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    while (child && child->isTableCol()) {
15528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        RenderTableCol* col = toRenderTableCol(child);
15628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int span = col->span();
15728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (col->firstChild())
15828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            groupLogicalWidth = col->style()->logicalWidth();
15928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        else {
16028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length colLogicalWidth = col->style()->logicalWidth();
16128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (colLogicalWidth.isAuto())
16228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                colLogicalWidth = groupLogicalWidth;
16328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if ((colLogicalWidth.isFixed() || colLogicalWidth.isPercent()) && colLogicalWidth.isZero())
16428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                colLogicalWidth = Length();
16528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            int effCol = m_table->colToEffCol(currentColumn);
16628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (!colLogicalWidth.isAuto() && span == 1 && effCol < nEffCols && m_table->spanOfEffCol(effCol) == 1) {
16728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                m_layoutStruct[effCol].logicalWidth = colLogicalWidth;
16828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (colLogicalWidth.isFixed() && m_layoutStruct[effCol].maxLogicalWidth < colLogicalWidth.value())
16928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    m_layoutStruct[effCol].maxLogicalWidth = colLogicalWidth.value();
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
17128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            currentColumn += span;
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        RenderObject* next = child->firstChild();
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!next)
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            next = child->nextSibling();
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!next && child->parent()->isTableCol()) {
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            next = child->parent()->nextSibling();
17928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            groupLogicalWidth = Length();
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        child = next;
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < nEffCols; i++)
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        recalcColumn(i);
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
18828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu// FIXME: This needs to be adapted for vertical writing modes.
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool shouldScaleColumns(RenderTable* table)
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // A special case.  If this table is not fixed width and contained inside
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // a cell, then don't bloat the maxwidth by examining percentage growth.
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool scale = true;
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (table) {
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Length tw = table->style()->width();
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ((tw.isAuto() || tw.isPercent()) && !table->isPositioned()) {
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RenderBlock* cb = table->containingBlock();
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (cb && !cb->isRenderView() && !cb->isTableCell() &&
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cb->style()->width().isAuto() && !cb->isPositioned())
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                cb = cb->containingBlock();
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            table = 0;
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (cb && cb->isTableCell() &&
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                (cb->style()->width().isAuto() || cb->style()->width().isPercent())) {
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (tw.isPercent())
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    scale = false;
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else {
2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                    RenderTableCell* cell = toRenderTableCell(cb);
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (cell->colSpan() > 1 || cell->table()->style()->width().isAuto())
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        scale = false;
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        table = cell->table();
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            table = 0;
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return scale;
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
222bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid AutoTableLayout::computePreferredLogicalWidths(int& minWidth, int& maxWidth)
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    fullRecalc();
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
22628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int spanMaxLogicalWidth = calcEffectiveLogicalWidth();
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    minWidth = 0;
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    maxWidth = 0;
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float maxPercent = 0;
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float maxNonPercent = 0;
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool scaleColumns = shouldScaleColumns(m_table);
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two places below to avoid division by zero.
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: Handle the 0% cases properly.
2352bde8e466a4451c7319e3a072d118917957d6554Steve Block    const float epsilon = 1 / 128.0f;
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2372bde8e466a4451c7319e3a072d118917957d6554Steve Block    float remainingPercent = 100;
23828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    for (size_t i = 0; i < m_layoutStruct.size(); ++i) {
23928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        minWidth += m_layoutStruct[i].effectiveMinLogicalWidth;
24028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth;
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (scaleColumns) {
24228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) {
2432bde8e466a4451c7319e3a072d118917957d6554Steve Block                float percent = min(static_cast<float>(m_layoutStruct[i].effectiveLogicalWidth.percent()), remainingPercent);
2442bde8e466a4451c7319e3a072d118917957d6554Steve Block                float logicalWidth = static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) * 100 / max(percent, epsilon);
24528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                maxPercent = max(logicalWidth,  maxPercent);
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                remainingPercent -= percent;
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
24828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth;
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (scaleColumns) {
2532bde8e466a4451c7319e3a072d118917957d6554Steve Block        maxNonPercent = maxNonPercent * 100 / max(remainingPercent, epsilon);
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        maxWidth = max(maxWidth, static_cast<int>(min(maxNonPercent, INT_MAX / 2.0f)));
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        maxWidth = max(maxWidth, static_cast<int>(min(maxPercent, INT_MAX / 2.0f)));
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    maxWidth = max(maxWidth, spanMaxLogicalWidth);
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int bordersPaddingAndSpacing = m_table->bordersPaddingAndSpacingInRowDirection();
26128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    minWidth += bordersPaddingAndSpacing;
26228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    maxWidth += bordersPaddingAndSpacing;
26328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
26428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    Length tableLogicalWidth = m_table->style()->logicalWidth();
26528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (tableLogicalWidth.isFixed() && tableLogicalWidth.value() > 0) {
26628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        minWidth = max(minWidth, tableLogicalWidth.value());
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        maxWidth = minWidth;
26854cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    } else if (!remainingPercent && maxNonPercent) {
26954cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block        // if there was no remaining percent, maxWidth is invalid.
2702bde8e466a4451c7319e3a072d118917957d6554Steve Block        maxWidth = intMaxForLength;
27154cdeeebc7adcbcd900e8b6a141a8cae27d9a631Steve Block    }
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project  This method takes care of colspans.
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project  effWidth is the same as width for cells without colspans. If we have colspans, they get modified.
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
27828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint AutoTableLayout::calcEffectiveLogicalWidth()
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
28028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    float maxLogicalWidth = 0;
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    size_t nEffCols = m_layoutStruct.size();
28328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int spacingInRowDirection = m_table->hBorderSpacing();
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    for (size_t i = 0; i < nEffCols; ++i) {
28628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        m_layoutStruct[i].effectiveLogicalWidth = m_layoutStruct[i].logicalWidth;
28728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        m_layoutStruct[i].effectiveMinLogicalWidth = m_layoutStruct[i].minLogicalWidth;
28828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        m_layoutStruct[i].effectiveMaxLogicalWidth = m_layoutStruct[i].maxLogicalWidth;
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    for (size_t i = 0; i < m_spanCells.size(); ++i) {
29228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        RenderTableCell* cell = m_spanCells[i];
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!cell)
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
29528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int span = cell->colSpan();
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        Length cellLogicalWidth = cell->styleOrColLogicalWidth();
29928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (!cellLogicalWidth.isRelative() && cellLogicalWidth.isZero())
30028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            cellLogicalWidth = Length(); // make it Auto
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int effCol = m_table->colToEffCol(cell->col());
30328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        size_t lastCol = effCol;
30428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRowDirection;
30528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        float cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRowDirection;
3062bde8e466a4451c7319e3a072d118917957d6554Steve Block        float totalPercent = 0;
30728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int spanMinLogicalWidth = 0;
30828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        float spanMaxLogicalWidth = 0;
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool allColsArePercent = true;
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool allColsAreFixed = true;
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool haveAuto = false;
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool spanHasEmptyCellsOnly = true;
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int fixedWidth = 0;
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (lastCol < nEffCols && span > 0) {
31528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Layout& columnLayout = m_layoutStruct[lastCol];
31628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            switch (columnLayout.logicalWidth.type()) {
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Percent:
3182bde8e466a4451c7319e3a072d118917957d6554Steve Block                totalPercent += columnLayout.logicalWidth.percent();
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                allColsAreFixed = false;
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                break;
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Fixed:
32228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (columnLayout.logicalWidth.value() > 0) {
32328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    fixedWidth += columnLayout.logicalWidth.value();
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    allColsArePercent = false;
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // IE resets effWidth to Auto here, but this breaks the konqueror about page and seems to be some bad
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // legacy behaviour anyway. mozilla doesn't do this so I decided we don't neither.
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // fall through
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case Auto:
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                haveAuto = true;
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // fall through
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            default:
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // If the column is a percentage width, do not let the spanning cell overwrite the
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // width value.  This caused a mis-rendering on amazon.com.
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Sample snippet:
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // <table border=2 width=100%><
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                //   <tr><td>1</td><td colspan=2>2-3</tr>
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                //   <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr>
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // </table>
34128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (!columnLayout.effectiveLogicalWidth.isPercent()) {
34228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    columnLayout.effectiveLogicalWidth = Length();
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    allColsArePercent = false;
34428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                } else
3452bde8e466a4451c7319e3a072d118917957d6554Steve Block                    totalPercent += columnLayout.effectiveLogicalWidth.percent();
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                allColsAreFixed = false;
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
34828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (!columnLayout.emptyCellsOnly)
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                spanHasEmptyCellsOnly = false;
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            span -= m_table->spanOfEffCol(lastCol);
35128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            spanMinLogicalWidth += columnLayout.effectiveMinLogicalWidth;
35228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            spanMaxLogicalWidth += columnLayout.effectiveMaxLogicalWidth;
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            lastCol++;
35428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            cellMinLogicalWidth -= spacingInRowDirection;
35528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            cellMaxLogicalWidth -= spacingInRowDirection;
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // adjust table max width if needed
35928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (cellLogicalWidth.isPercent()) {
3602bde8e466a4451c7319e3a072d118917957d6554Steve Block            if (totalPercent > cellLogicalWidth.percent() || allColsArePercent) {
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // can't satify this condition, treat as variable
36228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                cellLogicalWidth = Length();
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
3642bde8e466a4451c7319e3a072d118917957d6554Steve Block                maxLogicalWidth = max(maxLogicalWidth, static_cast<float>(max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100  / cellLogicalWidth.percent()));
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
366d0825bca7fe65beaee391d30da42e937db621564Steve Block                // all non percent columns in the span get percent values to sum up correctly.
3672bde8e466a4451c7319e3a072d118917957d6554Steve Block                float percentMissing = cellLogicalWidth.percent() - totalPercent;
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                float totalWidth = 0;
36928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                for (unsigned pos = effCol; pos < lastCol; ++pos) {
37028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent())
37128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWidth;
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
37428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++pos) {
37528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) {
3762bde8e466a4451c7319e3a072d118917957d6554Steve Block                        float percent = percentMissing * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / totalWidth;
37728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        percentMissing -= percent;
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (percent > 0)
3802bde8e466a4451c7319e3a072d118917957d6554Steve Block                            m_layoutStruct[pos].effectiveLogicalWidth.setValue(Percent, percent);
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        else
38228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                            m_layoutStruct[pos].effectiveLogicalWidth = Length();
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // make sure minWidth and maxWidth of the spanning cell are honoured
38928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (cellMinLogicalWidth > spanMinLogicalWidth) {
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (allColsAreFixed) {
39128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++pos) {
39228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int cellLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, cellMinLogicalWidth * m_layoutStruct[pos].logicalWidth.value() / fixedWidth);
39328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    fixedWidth -= m_layoutStruct[pos].logicalWidth.value();
39428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    cellMinLogicalWidth -= cellLogicalWidth;
39528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWidth;
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
39828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                float remainingMaxLogicalWidth = spanMaxLogicalWidth;
39928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                int remainingMinLogicalWidth = spanMinLogicalWidth;
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Give min to variable first, to fixed second, and to others third.
40228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol; ++pos) {
40328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth) {
40428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        int colMinLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value());
40528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        fixedWidth -= m_layoutStruct[pos].logicalWidth.value();
40628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth;
40728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
40828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        cellMinLogicalWidth -= colMinLogicalWidth;
40928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLogicalWidth;
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) {
41428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth)) {
41528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        int colMinLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMinLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / remainingMaxLogicalWidth : cellMinLogicalWidth));
41628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        colMinLogicalWidth = min(m_layoutStruct[pos].effectiveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colMinLogicalWidth);
41728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
41828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth;
41928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        cellMinLogicalWidth -= colMinLogicalWidth;
42028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                        m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLogicalWidth;
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
42528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (!cellLogicalWidth.isPercent()) {
42628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (cellMaxLogicalWidth > spanMaxLogicalWidth) {
42728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < lastCol; ++pos) {
42828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int colMaxLogicalWidth = max(m_layoutStruct[pos].effectiveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogicalWidth : cellMaxLogicalWidth));
42928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
43028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    cellMaxLogicalWidth -= colMaxLogicalWidth;
43128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogicalWidth;
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
43528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (unsigned pos = effCol; pos < lastCol; ++pos)
43628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                m_layoutStruct[pos].maxLogicalWidth = max(m_layoutStruct[pos].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth);
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // treat span ranges consisting of empty cells only as if they had content
43928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (spanHasEmptyCellsOnly) {
44028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (unsigned pos = effCol; pos < lastCol; ++pos)
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_layoutStruct[pos].emptyCellsOnly = false;
44228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        }
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
44428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    m_effectiveLogicalWidthDirty = false;
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
44628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return static_cast<int>(min(maxLogicalWidth, INT_MAX / 2.0f));
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* gets all cells that originate in a column and have a cellspan > 1
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project   Sorts them by increasing cellspan
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid AutoTableLayout::insertSpanCell(RenderTableCell *cell)
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
45428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    ASSERT_ARG(cell, cell && cell->colSpan() != 1);
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!cell || cell->colSpan() == 1)
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int size = m_spanCells.size();
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!size || m_spanCells[size-1] != 0) {
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_spanCells.grow(size + 10);
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (int i = 0; i < 10; i++)
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_spanCells[size+i] = 0;
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        size += 10;
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // add them in sort. This is a slow algorithm, and a binary search or a fast sorting after collection would be better
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned int pos = 0;
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int span = cell->colSpan();
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (pos < m_spanCells.size() && m_spanCells[pos] && span > m_spanCells[pos]->colSpan())
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pos++;
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memmove(m_spanCells.data()+pos+1, m_spanCells.data()+pos, (size-pos-1)*sizeof(RenderTableCell *));
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_spanCells[pos] = cell;
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid AutoTableLayout::layout()
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
478bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block#ifdef ANDROID_LAYOUT
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_table->isSingleColumn())
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
481bc7b84de3fd863c500a8169fd00dca3811cadbb3Steve Block#endif
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // table layout based on the values collected in the layout structure.
48328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection();
48428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    int available = tableLogicalWidth;
48528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    size_t nEffCols = m_table->numEffCols();
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (nEffCols != m_layoutStruct.size()) {
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fullRecalc();
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        nEffCols = m_table->numEffCols();
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (m_effectiveLogicalWidthDirty)
49328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        calcEffectiveLogicalWidth();
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool havePercent = false;
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int totalRelative = 0;
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int numAuto = 0;
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int numFixed = 0;
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float totalAuto = 0;
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float totalFixed = 0;
5012bde8e466a4451c7319e3a072d118917957d6554Steve Block    float totalPercent = 0;
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int allocAuto = 0;
50328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    unsigned numAutoEmptyCellsOnly = 0;
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // fill up every cell with its minWidth
50628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    for (size_t i = 0; i < nEffCols; ++i) {
50728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        int cellLogicalWidth = m_layoutStruct[i].effectiveMinLogicalWidth;
50828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
50928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        available -= cellLogicalWidth;
51028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
51128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        switch (logicalWidth.type()) {
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Percent:
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            havePercent = true;
5142bde8e466a4451c7319e3a072d118917957d6554Steve Block            totalPercent += logicalWidth.percent();
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Relative:
51728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            totalRelative += logicalWidth.value();
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Fixed:
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            numFixed++;
52128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            totalFixed += m_layoutStruct[i].effectiveMaxLogicalWidth;
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // fall through
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        case Auto:
52528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (m_layoutStruct[i].emptyCellsOnly)
52628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                numAutoEmptyCellsOnly++;
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else {
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                numAuto++;
52928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                totalAuto += m_layoutStruct[i].effectiveMaxLogicalWidth;
53028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                allocAuto += cellLogicalWidth;
5318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        default:
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            break;
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // allocate width to percent cols
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (available > 0 && havePercent) {
54028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        for (size_t i = 0; i < nEffCols; ++i) {
54128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
54228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (logicalWidth.isPercent()) {
54328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                int cellLogicalWidth = max(m_layoutStruct[i].effectiveMinLogicalWidth, logicalWidth.calcMinValue(tableLogicalWidth));
54428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth;
54528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5482bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (totalPercent > 100) {
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // remove overallocated space from the last columns
5502bde8e466a4451c7319e3a072d118917957d6554Steve Block            int excess = tableLogicalWidth * (totalPercent - 100) / 100;
55128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols - 1; i >= 0; --i) {
55228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) {
55328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidth;
55428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int reduction = min(cellLogicalWidth,  excess);
5558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // the lines below might look inconsistent, but that's the way it's handled in mozilla
5568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    excess -= reduction;
55728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int newLogicalWidth = max(m_layoutStruct[i].effectiveMinLogicalWidth, cellLogicalWidth - reduction);
55828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    available += cellLogicalWidth - newLogicalWidth;
55928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    m_layoutStruct[i].computedLogicalWidth = newLogicalWidth;
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // then allocate width to fixed cols
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (available > 0) {
56728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        for (size_t i = 0; i < nEffCols; ++i) {
56828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
56928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[i].computedLogicalWidth) {
57028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                available += m_layoutStruct[i].computedLogicalWidth - logicalWidth.value();
57128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                m_layoutStruct[i].computedLogicalWidth = logicalWidth.value();
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // now satisfy relative
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (available > 0) {
57828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        for (size_t i = 0; i < nEffCols; ++i) {
57928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
58028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (logicalWidth.isRelative() && logicalWidth.value() != 0) {
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // width=0* gets effMinWidth.
58228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                int cellLogicalWidth = logicalWidth.value() * tableLogicalWidth / totalRelative;
58328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth;
58428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // now satisfy variable
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (available > 0 && numAuto) {
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        available += allocAuto; // this gets redistributed
59228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        for (size_t i = 0; i < nEffCols; ++i) {
59328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
59428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCellsOnly) {
59528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                int cellLogicalWidth = max(m_layoutStruct[i].computedLogicalWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalAuto));
59628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                available -= cellLogicalWidth;
59728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth;
59828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // spread over fixed columns
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (available > 0 && numFixed) {
60528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        for (size_t i = 0; i < nEffCols; ++i) {
60628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
60728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (logicalWidth.isFixed()) {
60828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                int cellLogicalWidth = static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalFixed);
60928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                available -= cellLogicalWidth;
61028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                totalFixed -= m_layoutStruct[i].effectiveMaxLogicalWidth;
61128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // spread over percent colums
6172bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (available > 0 && m_hasPercent && totalPercent < 100) {
61828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        for (size_t i = 0; i < nEffCols; ++i) {
61928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
62028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (logicalWidth.isPercent()) {
6212bde8e466a4451c7319e3a072d118917957d6554Steve Block                int cellLogicalWidth = available * logicalWidth.percent() / totalPercent;
62228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                available -= cellLogicalWidth;
6232bde8e466a4451c7319e3a072d118917957d6554Steve Block                totalPercent -= logicalWidth.percent();
62428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
62528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (!available || !totalPercent)
62628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    break;
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // spread over the rest
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (available > 0 && nEffCols > numAutoEmptyCellsOnly) {
6338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int total = nEffCols - numAutoEmptyCellsOnly;
6348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // still have some width to spread
63528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        for (int i = nEffCols - 1; i >= 0; --i) {
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // variable columns with empty cells only don't get any width
63728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            if (m_layoutStruct[i].effectiveLogicalWidth.isAuto() && m_layoutStruct[i].emptyCellsOnly)
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                continue;
63928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            int cellLogicalWidth = available / total;
64028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            available -= cellLogicalWidth;
6418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            total--;
64228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
6438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
646d0825bca7fe65beaee391d30da42e937db621564Steve Block    // If we have overallocated, reduce every cell according to the difference between desired width and minwidth
647d0825bca7fe65beaee391d30da42e937db621564Steve Block    // this seems to produce to the pixel exact results with IE. Wonder is some of this also holds for width distributing.
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (available < 0) {
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Need to reduce cells with the following prioritization:
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // (1) Auto
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // (2) Relative
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // (3) Fixed
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // (4) Percent
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This is basically the reverse of how we grew the cells.
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (available < 0) {
65628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            int logicalWidthBeyondMin = 0;
65728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols - 1; i >= 0; --i) {
65828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
65928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (logicalWidth.isAuto())
66028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
66328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) {
66428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
66528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (logicalWidth.isAuto()) {
66628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
66728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int reduce = available * minMaxDiff / logicalWidthBeyondMin;
66828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    m_layoutStruct[i].computedLogicalWidth += reduce;
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    available -= reduce;
67028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    logicalWidthBeyondMin -= minMaxDiff;
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (available >= 0)
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (available < 0) {
67828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            int logicalWidthBeyondMin = 0;
67928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols - 1; i >= 0; --i) {
68028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
68128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (logicalWidth.isRelative())
68228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
68528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) {
68628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
68728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (logicalWidth.isRelative()) {
68828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
68928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int reduce = available * minMaxDiff / logicalWidthBeyondMin;
69028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    m_layoutStruct[i].computedLogicalWidth += reduce;
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    available -= reduce;
69228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    logicalWidthBeyondMin -= minMaxDiff;
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (available >= 0)
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
6968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (available < 0) {
70028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            int logicalWidthBeyondMin = 0;
70128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols - 1; i >= 0; --i) {
70228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
70328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (logicalWidth.isFixed())
70428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
70728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) {
70828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
70928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (logicalWidth.isFixed()) {
71028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
71128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int reduce = available * minMaxDiff / logicalWidthBeyondMin;
71228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    m_layoutStruct[i].computedLogicalWidth += reduce;
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    available -= reduce;
71428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    logicalWidthBeyondMin -= minMaxDiff;
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (available >= 0)
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (available < 0) {
72228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            int logicalWidthBeyondMin = 0;
72328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols - 1; i >= 0; --i) {
72428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
72528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (logicalWidth.isPercent())
72628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
72928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            for (int i = nEffCols-1; i >= 0 && logicalWidthBeyondMin > 0; i--) {
73028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
73128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                if (logicalWidth.isPercent()) {
73228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
73328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    int reduce = available * minMaxDiff / logicalWidthBeyondMin;
73428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    m_layoutStruct[i].computedLogicalWidth += reduce;
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    available -= reduce;
73628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    logicalWidthBeyondMin -= minMaxDiff;
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (available >= 0)
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        break;
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int pos = 0;
74528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    for (size_t i = 0; i < nEffCols; ++i) {
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_table->columnPositions()[i] = pos;
74728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing();
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_table->columnPositions()[m_table->columnPositions().size() - 1] = pos;
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
753