Changeset 71262 in webkit


Ignore:
Timestamp:
Nov 3, 2010 1:44:49 PM (13 years ago)
Author:
mitz@apple.com
Message:

Made table column width allocation algorithms use logical widths.

Reviewed by Dave Hyatt.

Part of: Make tables work with vertical text
https://bugs.webkit.org/show_bug.cgi?id=46417

No new tests since tables don’t support different block flows yet.

  • rendering/AutoTableLayout.cpp:

(WebCore::AutoTableLayout::AutoTableLayout):
(WebCore::AutoTableLayout::recalcColumn):
(WebCore::AutoTableLayout::fullRecalc):
(WebCore::AutoTableLayout::computePreferredLogicalWidths):
(WebCore::AutoTableLayout::calcEffectiveLogicalWidth):
(WebCore::AutoTableLayout::insertSpanCell):
(WebCore::AutoTableLayout::layout):

  • rendering/AutoTableLayout.h:

(WebCore::AutoTableLayout::Layout::Layout):

  • rendering/FixedTableLayout.cpp:

(WebCore::FixedTableLayout::calcWidthArray):
(WebCore::FixedTableLayout::computePreferredLogicalWidths):
(WebCore::FixedTableLayout::layout):

  • rendering/FixedTableLayout.h:
  • rendering/RenderTable.h:

(WebCore::RenderTable::bordersPaddingAndSpacingInRowDirection): Renamed, but not changed yet.

Location:
trunk/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r71260 r71262  
     12010-11-03  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Dave Hyatt.
     4
     5        Made table column width allocation algorithms use logical widths.
     6
     7        Part of: Make tables work with vertical text
     8        https://bugs.webkit.org/show_bug.cgi?id=46417
     9
     10        No new tests since tables don’t support different block flows yet.
     11
     12        * rendering/AutoTableLayout.cpp:
     13        (WebCore::AutoTableLayout::AutoTableLayout):
     14        (WebCore::AutoTableLayout::recalcColumn):
     15        (WebCore::AutoTableLayout::fullRecalc):
     16        (WebCore::AutoTableLayout::computePreferredLogicalWidths):
     17        (WebCore::AutoTableLayout::calcEffectiveLogicalWidth):
     18        (WebCore::AutoTableLayout::insertSpanCell):
     19        (WebCore::AutoTableLayout::layout):
     20        * rendering/AutoTableLayout.h:
     21        (WebCore::AutoTableLayout::Layout::Layout):
     22        * rendering/FixedTableLayout.cpp:
     23        (WebCore::FixedTableLayout::calcWidthArray):
     24        (WebCore::FixedTableLayout::computePreferredLogicalWidths):
     25        (WebCore::FixedTableLayout::layout):
     26        * rendering/FixedTableLayout.h:
     27        * rendering/RenderTable.h:
     28        (WebCore::RenderTable::bordersPaddingAndSpacingInRowDirection): Renamed, but not changed yet.
     29
    1302010-11-03  No'am Rosenthal  <noam.rosenthal@nokia.com>
    231
  • trunk/WebCore/rendering/AutoTableLayout.cpp

    r71251 r71262  
    22 * Copyright (C) 2002 Lars Knoll (knoll@kde.org)
    33 *           (C) 2002 Dirk Mueller (mueller@kde.org)
    4  * Copyright (C) 2003, 2006, 2008 Apple Inc. All rights reserved.
     4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved.
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    3535    : TableLayout(table)
    3636    , m_hasPercent(false)
    37     , m_effWidthDirty(true)
     37    , m_effectiveLogicalWidthDirty(true)
    3838{
    3939}
     
    4343}
    4444
    45 /* recalculates the full structure needed to do layouting and minmax calculations.
    46    This is usually calculated on the fly, but needs to be done fully when table cells change
    47    dynamically
    48 */
    4945void AutoTableLayout::recalcColumn(int effCol)
    5046{
    51     Layout &l = m_layoutStruct[effCol];
    52 
    53     RenderObject* child = m_table->firstChild();
    54     // first we iterate over all rows.
     47    Layout& columnLayout = m_layoutStruct[effCol];
    5548
    5649    RenderTableCell* fixedContributor = 0;
    5750    RenderTableCell* maxContributor = 0;
    5851
    59     while (child) {
     52    for (RenderObject* child = m_table->firstChild(); child; child = child->nextSibling()) {
    6053        if (child->isTableCol())
    6154            toRenderTableCol(child)->computePreferredLogicalWidths();
     
    6962                bool cellHasContent = cell && !current.inColSpan && (cell->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding());
    7063                if (cellHasContent)
    71                     l.emptyCellsOnly = false;
     64                    columnLayout.emptyCellsOnly = false;
    7265                   
    73                 if (current.inColSpan)
     66                if (current.inColSpan || !cell)
    7467                    continue;
    75                 if (cell && cell->colSpan() == 1) {
     68
     69                if (cell->colSpan() == 1) {
    7670                    // A cell originates in this column.  Ensure we have
    7771                    // a min/max width of at least 1px for this column now.
    78                     l.minWidth = max(l.minWidth, cellHasContent ? 1 : 0);
    79                     l.maxWidth = max(l.maxWidth, 1);
     72                    columnLayout.minLogicalWidth = max(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0);
     73                    columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, 1);
    8074                    if (cell->preferredLogicalWidthsDirty())
    8175                        cell->computePreferredLogicalWidths();
    82                     l.minWidth = max(cell->minPreferredLogicalWidth(), l.minWidth);
    83                     if (cell->maxPreferredLogicalWidth() > l.maxWidth) {
    84                         l.maxWidth = cell->maxPreferredLogicalWidth();
     76                    columnLayout.minLogicalWidth = max(cell->minPreferredLogicalWidth(), columnLayout.minLogicalWidth);
     77                    if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) {
     78                        columnLayout.maxLogicalWidth = cell->maxPreferredLogicalWidth();
    8579                        maxContributor = cell;
    8680                    }
    8781
    88                     Length w = cell->styleOrColLogicalWidth();
     82                    Length cellLogicalWidth = cell->styleOrColLogicalWidth();
    8983                    // FIXME: What is this arbitrary value?
    90                     if (w.rawValue() > 32760)
    91                         w.setRawValue(32760);
    92                     if (w.isNegative())
    93                         w.setValue(0);
    94                     switch (w.type()) {
     84                    if (cellLogicalWidth.rawValue() > 32760)
     85                        cellLogicalWidth.setRawValue(32760);
     86                    if (cellLogicalWidth.isNegative())
     87                        cellLogicalWidth.setValue(0);
     88                    switch (cellLogicalWidth.type()) {
    9589                    case Fixed:
    9690                        // ignore width=0
    97                         if (w.value() > 0 && (int)l.width.type() != Percent) {
    98                             int wval = cell->computeBorderBoxLogicalWidth(w.value());
    99                             if (l.width.isFixed()) {
     91                        if (cellLogicalWidth.value() > 0 && columnLayout.logicalWidth.type() != Percent) {
     92                            int logicalWidth = cell->computeBorderBoxLogicalWidth(cellLogicalWidth.value());
     93                            if (columnLayout.logicalWidth.isFixed()) {
    10094                                // Nav/IE weirdness
    101                                 if ((wval > l.width.value()) ||
    102                                     ((l.width.value() == wval) && (maxContributor == cell))) {
    103                                     l.width.setValue(wval);
     95                                if ((logicalWidth > columnLayout.logicalWidth.value()) ||
     96                                    ((columnLayout.logicalWidth.value() == logicalWidth) && (maxContributor == cell))) {
     97                                    columnLayout.logicalWidth.setValue(logicalWidth);
    10498                                    fixedContributor = cell;
    10599                                }
    106100                            } else {
    107                                 l.width.setValue(Fixed, wval);
     101                                columnLayout.logicalWidth.setValue(Fixed, logicalWidth);
    108102                                fixedContributor = cell;
    109103                            }
     
    112106                    case Percent:
    113107                        m_hasPercent = true;
    114                         if (w.isPositive() && (!l.width.isPercent() || w.rawValue() > l.width.rawValue()))
    115                             l.width = w;
     108                        if (cellLogicalWidth.isPositive() && (!columnLayout.logicalWidth.isPercent() || cellLogicalWidth.rawValue() > columnLayout.logicalWidth.rawValue()))
     109                            columnLayout.logicalWidth = cellLogicalWidth;
    116110                        break;
    117111                    case Relative:
    118112                        // FIXME: Need to understand this case and whether it makes sense to compare values
    119113                        // which are not necessarily of the same type.
    120                         if (w.isAuto() || (w.isRelative() && w.value() > l.width.rawValue()))
    121                             l.width = w;
     114                        if (cellLogicalWidth.isAuto() || (cellLogicalWidth.isRelative() && cellLogicalWidth.value() > columnLayout.logicalWidth.rawValue()))
     115                            columnLayout.logicalWidth = cellLogicalWidth;
    122116                    default:
    123117                        break;
    124118                    }
    125                 } else {
    126                     if (cell && (!effCol || section->primaryCellAt(i, effCol-1) != cell)) {
    127                         // This spanning cell originates in this column.  Ensure we have
    128                         // a min/max width of at least 1px for this column now.
    129                         l.minWidth = max(l.minWidth, cellHasContent ? 1 : 0);
    130                         l.maxWidth = max(l.maxWidth, 1);
    131                         insertSpanCell(cell);
    132                     }
    133                 }
    134             }
    135         }
    136         child = child->nextSibling();
     119                } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) {
     120                    // This spanning cell originates in this column.  Ensure we have
     121                    // a min/max width of at least 1px for this column now.
     122                    columnLayout.minLogicalWidth = max(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0);
     123                    columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, 1);
     124                    insertSpanCell(cell);
     125                }
     126            }
     127        }
    137128    }
    138129
    139130    // Nav/IE weirdness
    140     if (l.width.isFixed()) {
    141         if (m_table->document()->inQuirksMode() && l.maxWidth > l.width.value() && fixedContributor != maxContributor) {
    142             l.width = Length();
     131    if (columnLayout.logicalWidth.isFixed()) {
     132        if (m_table->document()->inQuirksMode() && columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() && fixedContributor != maxContributor) {
     133            columnLayout.logicalWidth = Length();
    143134            fixedContributor = 0;
    144135        }
    145136    }
    146137
    147     l.maxWidth = max(l.maxWidth, l.minWidth);
    148 
    149     // ### we need to add col elements as well
     138    columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, columnLayout.minLogicalWidth);
    150139}
    151140
     
    153142{
    154143    m_hasPercent = false;
    155     m_effWidthDirty = true;
     144    m_effectiveLogicalWidthDirty = true;
    156145
    157146    int nEffCols = m_table->numEffCols();
     
    160149    m_spanCells.fill(0);
    161150
    162     RenderObject *child = m_table->firstChild();
    163     Length grpWidth;
    164     int cCol = 0;
    165     while (child) {
    166         if (child->isTableCol()) {
    167             RenderTableCol *col = toRenderTableCol(child);
    168             int span = col->span();
    169             if (col->firstChild()) {
    170                 grpWidth = col->style()->width();
    171             } else {
    172                 Length w = col->style()->width();
    173                 if (w.isAuto())
    174                     w = grpWidth;
    175                 if ((w.isFixed() || w.isPercent()) && w.isZero())
    176                     w = Length();
    177                 int cEffCol = m_table->colToEffCol(cCol);
    178                 if (!w.isAuto() && span == 1 && cEffCol < nEffCols) {
    179                     if (m_table->spanOfEffCol(cEffCol) == 1) {
    180                         m_layoutStruct[cEffCol].width = w;
    181                         if (w.isFixed() && m_layoutStruct[cEffCol].maxWidth < w.value())
    182                             m_layoutStruct[cEffCol].maxWidth = w.value();
    183                     }
    184                 }
    185                 cCol += span;
    186             }
    187         } else {
    188             break;
    189         }
    190 
    191         RenderObject *next = child->firstChild();
     151    RenderObject* child = m_table->firstChild();
     152    Length groupLogicalWidth;
     153    int currentColumn = 0;
     154    while (child && child->isTableCol()) {
     155        RenderTableCol* col = toRenderTableCol(child);
     156        int span = col->span();
     157        if (col->firstChild())
     158            groupLogicalWidth = col->style()->logicalWidth();
     159        else {
     160            Length colLogicalWidth = col->style()->logicalWidth();
     161            if (colLogicalWidth.isAuto())
     162                colLogicalWidth = groupLogicalWidth;
     163            if ((colLogicalWidth.isFixed() || colLogicalWidth.isPercent()) && colLogicalWidth.isZero())
     164                colLogicalWidth = Length();
     165            int effCol = m_table->colToEffCol(currentColumn);
     166            if (!colLogicalWidth.isAuto() && span == 1 && effCol < nEffCols && m_table->spanOfEffCol(effCol) == 1) {
     167                m_layoutStruct[effCol].logicalWidth = colLogicalWidth;
     168                if (colLogicalWidth.isFixed() && m_layoutStruct[effCol].maxLogicalWidth < colLogicalWidth.value())
     169                    m_layoutStruct[effCol].maxLogicalWidth = colLogicalWidth.value();
     170            }
     171            currentColumn += span;
     172        }
     173
     174        RenderObject* next = child->firstChild();
    192175        if (!next)
    193176            next = child->nextSibling();
    194177        if (!next && child->parent()->isTableCol()) {
    195178            next = child->parent()->nextSibling();
    196             grpWidth = Length();
     179            groupLogicalWidth = Length();
    197180        }
    198181        child = next;
    199182    }
    200 
    201183
    202184    for (int i = 0; i < nEffCols; i++)
     
    204186}
    205187
     188// FIXME: This needs to be adapted for vertical writing modes.
    206189static bool shouldScaleColumns(RenderTable* table)
    207190{
     
    241224    fullRecalc();
    242225
    243     int spanMaxWidth = calcEffectiveWidth();
     226    int spanMaxLogicalWidth = calcEffectiveLogicalWidth();
    244227    minWidth = 0;
    245228    maxWidth = 0;
     
    253236
    254237    int remainingPercent = 100 * percentScaleFactor;
    255     for (unsigned int i = 0; i < m_layoutStruct.size(); i++) {
    256         minWidth += m_layoutStruct[i].effMinWidth;
    257         maxWidth += m_layoutStruct[i].effMaxWidth;
     238    for (size_t i = 0; i < m_layoutStruct.size(); ++i) {
     239        minWidth += m_layoutStruct[i].effectiveMinLogicalWidth;
     240        maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth;
    258241        if (scaleColumns) {
    259             if (m_layoutStruct[i].effWidth.isPercent()) {
    260                 int percent = min(m_layoutStruct[i].effWidth.rawValue(), remainingPercent);
    261                 float pw = static_cast<float>(m_layoutStruct[i].effMaxWidth) * 100 * percentScaleFactor / max(percent, epsilon);
    262                 maxPercent = max(pw,  maxPercent);
     242            if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) {
     243                int percent = min(m_layoutStruct[i].effectiveLogicalWidth.rawValue(), remainingPercent);
     244                float logicalWidth = static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) * 100 * percentScaleFactor / max(percent, epsilon);
     245                maxPercent = max(logicalWidth,  maxPercent);
    263246                remainingPercent -= percent;
    264247            } else
    265                 maxNonPercent += m_layoutStruct[i].effMaxWidth;
     248                maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth;
    266249        }
    267250    }
     
    273256    }
    274257
    275     maxWidth = max(maxWidth, spanMaxWidth);
    276    
    277     int bs = m_table->bordersPaddingAndSpacing();
    278     minWidth += bs;
    279     maxWidth += bs;
    280 
    281     Length tw = m_table->style()->width();
    282     if (tw.isFixed() && tw.value() > 0) {
    283         minWidth = max(minWidth, tw.value());
     258    maxWidth = max(maxWidth, spanMaxLogicalWidth);
     259
     260    int bordersPaddingAndSpacing = m_table->bordersPaddingAndSpacingInRowDirection();
     261    minWidth += bordersPaddingAndSpacing;
     262    maxWidth += bordersPaddingAndSpacing;
     263
     264    Length tableLogicalWidth = m_table->style()->logicalWidth();
     265    if (tableLogicalWidth.isFixed() && tableLogicalWidth.value() > 0) {
     266        minWidth = max(minWidth, tableLogicalWidth.value());
    284267        maxWidth = minWidth;
    285268    }
     
    290273  effWidth is the same as width for cells without colspans. If we have colspans, they get modified.
    291274 */
    292 int AutoTableLayout::calcEffectiveWidth()
    293 {
    294     float tMaxWidth = 0;
    295 
    296     unsigned int nEffCols = m_layoutStruct.size();
    297     int hspacing = m_table->hBorderSpacing();
    298 
    299     for (unsigned int i = 0; i < nEffCols; i++) {
    300         m_layoutStruct[i].effWidth = m_layoutStruct[i].width;
    301         m_layoutStruct[i].effMinWidth = m_layoutStruct[i].minWidth;
    302         m_layoutStruct[i].effMaxWidth = m_layoutStruct[i].maxWidth;
    303     }
    304 
    305     for (unsigned int i = 0; i < m_spanCells.size(); i++) {
    306         RenderTableCell *cell = m_spanCells[i];
     275int AutoTableLayout::calcEffectiveLogicalWidth()
     276{
     277    float maxLogicalWidth = 0;
     278
     279    size_t nEffCols = m_layoutStruct.size();
     280    int spacingInRowDirection = m_table->hBorderSpacing();
     281
     282    for (size_t i = 0; i < nEffCols; ++i) {
     283        m_layoutStruct[i].effectiveLogicalWidth = m_layoutStruct[i].logicalWidth;
     284        m_layoutStruct[i].effectiveMinLogicalWidth = m_layoutStruct[i].minLogicalWidth;
     285        m_layoutStruct[i].effectiveMaxLogicalWidth = m_layoutStruct[i].maxLogicalWidth;
     286    }
     287
     288    for (size_t i = 0; i < m_spanCells.size(); ++i) {
     289        RenderTableCell* cell = m_spanCells[i];
    307290        if (!cell)
    308291            break;
     292
    309293        int span = cell->colSpan();
    310294
    311         Length w = cell->styleOrColLogicalWidth();
    312         if (!w.isRelative() && w.isZero())
    313             w = Length(); // make it Auto
    314 
    315         int col = m_table->colToEffCol(cell->col());
    316         unsigned int lastCol = col;
    317         int cMinWidth = cell->minPreferredLogicalWidth() + hspacing;
    318         float cMaxWidth = cell->maxPreferredLogicalWidth() + hspacing;
     295        Length cellLogicalWidth = cell->styleOrColLogicalWidth();
     296        if (!cellLogicalWidth.isRelative() && cellLogicalWidth.isZero())
     297            cellLogicalWidth = Length(); // make it Auto
     298
     299        int effCol = m_table->colToEffCol(cell->col());
     300        size_t lastCol = effCol;
     301        int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRowDirection;
     302        float cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRowDirection;
    319303        int totalPercent = 0;
    320         int minWidth = 0;
    321         float maxWidth = 0;
     304        int spanMinLogicalWidth = 0;
     305        float spanMaxLogicalWidth = 0;
    322306        bool allColsArePercent = true;
    323307        bool allColsAreFixed = true;
     
    326310        int fixedWidth = 0;
    327311        while (lastCol < nEffCols && span > 0) {
    328             switch (m_layoutStruct[lastCol].width.type()) {
     312            Layout& columnLayout = m_layoutStruct[lastCol];
     313            switch (columnLayout.logicalWidth.type()) {
    329314            case Percent:
    330                 totalPercent += m_layoutStruct[lastCol].width.rawValue();
     315                totalPercent += columnLayout.logicalWidth.rawValue();
    331316                allColsAreFixed = false;
    332317                break;
    333318            case Fixed:
    334                 if (m_layoutStruct[lastCol].width.value() > 0) {
    335                     fixedWidth += m_layoutStruct[lastCol].width.value();
     319                if (columnLayout.logicalWidth.value() > 0) {
     320                    fixedWidth += columnLayout.logicalWidth.value();
    336321                    allColsArePercent = false;
    337322                    // IE resets effWidth to Auto here, but this breaks the konqueror about page and seems to be some bad
     
    351336                //   <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr>
    352337                // </table>
    353                 if (!m_layoutStruct[lastCol].effWidth.isPercent()) {
    354                     m_layoutStruct[lastCol].effWidth = Length();
     338                if (!columnLayout.effectiveLogicalWidth.isPercent()) {
     339                    columnLayout.effectiveLogicalWidth = Length();
    355340                    allColsArePercent = false;
    356                 }
    357                 else
    358                     totalPercent += m_layoutStruct[lastCol].effWidth.rawValue();
     341                } else
     342                    totalPercent += columnLayout.effectiveLogicalWidth.rawValue();
    359343                allColsAreFixed = false;
    360344            }
    361             if (!m_layoutStruct[lastCol].emptyCellsOnly)
     345            if (!columnLayout.emptyCellsOnly)
    362346                spanHasEmptyCellsOnly = false;
    363347            span -= m_table->spanOfEffCol(lastCol);
    364             minWidth += m_layoutStruct[lastCol].effMinWidth;
    365             maxWidth += m_layoutStruct[lastCol].effMaxWidth;
     348            spanMinLogicalWidth += columnLayout.effectiveMinLogicalWidth;
     349            spanMaxLogicalWidth += columnLayout.effectiveMaxLogicalWidth;
    366350            lastCol++;
    367             cMinWidth -= hspacing;
    368             cMaxWidth -= hspacing;
     351            cellMinLogicalWidth -= spacingInRowDirection;
     352            cellMaxLogicalWidth -= spacingInRowDirection;
    369353        }
    370354
    371355        // adjust table max width if needed
    372         if (w.isPercent()) {
    373             if (totalPercent > w.rawValue() || allColsArePercent) {
     356        if (cellLogicalWidth.isPercent()) {
     357            if (totalPercent > cellLogicalWidth.rawValue() || allColsArePercent) {
    374358                // can't satify this condition, treat as variable
    375                 w = Length();
     359                cellLogicalWidth = Length();
    376360            } else {
    377                 float spanMax = max(maxWidth, cMaxWidth);
    378                 tMaxWidth = max(tMaxWidth, spanMax * 100 * percentScaleFactor / w.rawValue());
     361                maxLogicalWidth = max(maxLogicalWidth, max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 * percentScaleFactor / cellLogicalWidth.rawValue());
    379362
    380363                // all non percent columns in the span get percent values to sum up correctly.
    381                 int percentMissing = w.rawValue() - totalPercent;
     364                int percentMissing = cellLogicalWidth.rawValue() - totalPercent;
    382365                float totalWidth = 0;
    383                 for (unsigned int pos = col; pos < lastCol; pos++) {
    384                     if (!(m_layoutStruct[pos].effWidth.isPercent()))
    385                         totalWidth += m_layoutStruct[pos].effMaxWidth;
    386                 }
    387 
    388                 for (unsigned int pos = col; pos < lastCol && totalWidth > 0; pos++) {
    389                     if (!(m_layoutStruct[pos].effWidth.isPercent())) {
    390                         int percent = static_cast<int>(percentMissing * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / totalWidth);
    391                         totalWidth -= m_layoutStruct[pos].effMaxWidth;
     366                for (unsigned pos = effCol; pos < lastCol; ++pos) {
     367                    if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent())
     368                        totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWidth;
     369                }
     370
     371                for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++pos) {
     372                    if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) {
     373                        int percent = static_cast<int>(percentMissing * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / totalWidth);
     374                        totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
    392375                        percentMissing -= percent;
    393376                        if (percent > 0)
    394                             m_layoutStruct[pos].effWidth.setRawValue(Percent, percent);
     377                            m_layoutStruct[pos].effectiveLogicalWidth.setRawValue(Percent, percent);
    395378                        else
    396                             m_layoutStruct[pos].effWidth = Length();
     379                            m_layoutStruct[pos].effectiveLogicalWidth = Length();
    397380                    }
    398381                }
    399 
    400382            }
    401383        }
    402384
    403385        // make sure minWidth and maxWidth of the spanning cell are honoured
    404         if (cMinWidth > minWidth) {
     386        if (cellMinLogicalWidth > spanMinLogicalWidth) {
    405387            if (allColsAreFixed) {
    406                 for (unsigned int pos = col; fixedWidth > 0 && pos < lastCol; pos++) {
    407                     int w = max(m_layoutStruct[pos].effMinWidth, cMinWidth * m_layoutStruct[pos].width.value() / fixedWidth);
    408                     fixedWidth -= m_layoutStruct[pos].width.value();
    409                     cMinWidth -= w;
    410                     m_layoutStruct[pos].effMinWidth = w;
    411                 }
    412 
     388                for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++pos) {
     389                    int cellLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, cellMinLogicalWidth * m_layoutStruct[pos].logicalWidth.value() / fixedWidth);
     390                    fixedWidth -= m_layoutStruct[pos].logicalWidth.value();
     391                    cellMinLogicalWidth -= cellLogicalWidth;
     392                    m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWidth;
     393                }
    413394            } else {
    414                 float maxw = maxWidth;
    415                 int minw = minWidth;
     395                float remainingMaxLogicalWidth = spanMaxLogicalWidth;
     396                int remainingMinLogicalWidth = spanMinLogicalWidth;
    416397               
    417398                // Give min to variable first, to fixed second, and to others third.
    418                 for (unsigned int pos = col; maxw >= 0 && pos < lastCol; pos++) {
    419                     if (m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth) {
    420                         int w = max(m_layoutStruct[pos].effMinWidth, m_layoutStruct[pos].width.value());
    421                         fixedWidth -= m_layoutStruct[pos].width.value();
    422                         minw -= m_layoutStruct[pos].effMinWidth;
    423                         maxw -= m_layoutStruct[pos].effMaxWidth;
    424                         cMinWidth -= w;
    425                         m_layoutStruct[pos].effMinWidth = w;
     399                for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol; ++pos) {
     400                    if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth) {
     401                        int colMinLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value());
     402                        fixedWidth -= m_layoutStruct[pos].logicalWidth.value();
     403                        remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth;
     404                        remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
     405                        cellMinLogicalWidth -= colMinLogicalWidth;
     406                        m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLogicalWidth;
    426407                    }
    427408                }
    428409
    429                 for (unsigned int pos = col; maxw >= 0 && pos < lastCol && minw < cMinWidth; pos++) {
    430                     if (!(m_layoutStruct[pos].width.isFixed() && haveAuto && fixedWidth <= cMinWidth)) {
    431                         int w = max(m_layoutStruct[pos].effMinWidth, static_cast<int>(maxw ? cMinWidth * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / maxw : cMinWidth));
    432                         w = min(m_layoutStruct[pos].effMinWidth+(cMinWidth-minw), w);
    433                                                
    434                         maxw -= m_layoutStruct[pos].effMaxWidth;
    435                         minw -= m_layoutStruct[pos].effMinWidth;
    436                         cMinWidth -= w;
    437                         m_layoutStruct[pos].effMinWidth = w;
     410                for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos < lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) {
     411                    if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto && fixedWidth <= cellMinLogicalWidth)) {
     412                        int colMinLogicalWidth = max(m_layoutStruct[pos].effectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMinLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / remainingMaxLogicalWidth : cellMinLogicalWidth));
     413                        colMinLogicalWidth = min(m_layoutStruct[pos].effectiveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colMinLogicalWidth);
     414                        remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
     415                        remainingMinLogicalWidth -= m_layoutStruct[pos].effectiveMinLogicalWidth;
     416                        cellMinLogicalWidth -= colMinLogicalWidth;
     417                        m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLogicalWidth;
    438418                    }
    439419                }
    440420            }
    441421        }
    442         if (!(w.isPercent())) {
    443             if (cMaxWidth > maxWidth) {
    444                 for (unsigned int pos = col; maxWidth >= 0 && pos < lastCol; pos++) {
    445                     int w = max(m_layoutStruct[pos].effMaxWidth, static_cast<int>(maxWidth ? cMaxWidth * static_cast<float>(m_layoutStruct[pos].effMaxWidth) / maxWidth : cMaxWidth));
    446                     maxWidth -= m_layoutStruct[pos].effMaxWidth;
    447                     cMaxWidth -= w;
    448                     m_layoutStruct[pos].effMaxWidth = w;
     422        if (!cellLogicalWidth.isPercent()) {
     423            if (cellMaxLogicalWidth > spanMaxLogicalWidth) {
     424                for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < lastCol; ++pos) {
     425                    int colMaxLogicalWidth = max(m_layoutStruct[pos].effectiveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogicalWidth : cellMaxLogicalWidth));
     426                    spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWidth;
     427                    cellMaxLogicalWidth -= colMaxLogicalWidth;
     428                    m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogicalWidth;
    449429                }
    450430            }
    451431        } else {
    452             for (unsigned int pos = col; pos < lastCol; pos++)
    453                 m_layoutStruct[pos].maxWidth = max(m_layoutStruct[pos].maxWidth, m_layoutStruct[pos].minWidth);
     432            for (unsigned pos = effCol; pos < lastCol; ++pos)
     433                m_layoutStruct[pos].maxLogicalWidth = max(m_layoutStruct[pos].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth);
    454434        }
    455435        // treat span ranges consisting of empty cells only as if they had content
    456         if (spanHasEmptyCellsOnly)
    457             for (unsigned int pos = col; pos < lastCol; pos++)
     436        if (spanHasEmptyCellsOnly) {
     437            for (unsigned pos = effCol; pos < lastCol; ++pos)
    458438                m_layoutStruct[pos].emptyCellsOnly = false;
    459     }
    460     m_effWidthDirty = false;
    461 
    462     return static_cast<int>(min(tMaxWidth, INT_MAX / 2.0f));
     439        }
     440    }
     441    m_effectiveLogicalWidthDirty = false;
     442
     443    return static_cast<int>(min(maxLogicalWidth, INT_MAX / 2.0f));
    463444}
    464445
     
    468449void AutoTableLayout::insertSpanCell(RenderTableCell *cell)
    469450{
     451    ASSERT_ARG(cell, cell && cell->colSpan() != 1);
    470452    if (!cell || cell->colSpan() == 1)
    471453        return;
     
    492474{
    493475    // table layout based on the values collected in the layout structure.
    494     int tableWidth = m_table->width() - m_table->bordersPaddingAndSpacing();
    495     int available = tableWidth;
    496     int nEffCols = m_table->numEffCols();
    497 
    498     if (nEffCols != (int)m_layoutStruct.size()) {
     476    int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection();
     477    int available = tableLogicalWidth;
     478    size_t nEffCols = m_table->numEffCols();
     479
     480    if (nEffCols != m_layoutStruct.size()) {
    499481        fullRecalc();
    500482        nEffCols = m_table->numEffCols();
    501483    }
    502484
    503     if (m_effWidthDirty)
    504         calcEffectiveWidth();
     485    if (m_effectiveLogicalWidthDirty)
     486        calcEffectiveLogicalWidth();
    505487
    506488    bool havePercent = false;
     
    512494    int totalPercent = 0;
    513495    int allocAuto = 0;
    514     int numAutoEmptyCellsOnly = 0;
     496    unsigned numAutoEmptyCellsOnly = 0;
    515497
    516498    // fill up every cell with its minWidth
    517     for (int i = 0; i < nEffCols; i++) {
    518         int w = m_layoutStruct[i].effMinWidth;
    519         m_layoutStruct[i].calcWidth = w;
    520         available -= w;
    521         Length& width = m_layoutStruct[i].effWidth;
    522         switch (width.type()) {
     499    for (size_t i = 0; i < nEffCols; ++i) {
     500        int cellLogicalWidth = m_layoutStruct[i].effectiveMinLogicalWidth;
     501        m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
     502        available -= cellLogicalWidth;
     503        Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     504        switch (logicalWidth.type()) {
    523505        case Percent:
    524506            havePercent = true;
    525             totalPercent += width.rawValue();
     507            totalPercent += logicalWidth.rawValue();
    526508            break;
    527509        case Relative:
    528             totalRelative += width.value();
     510            totalRelative += logicalWidth.value();
    529511            break;
    530512        case Fixed:
    531513            numFixed++;
    532             totalFixed += m_layoutStruct[i].effMaxWidth;
     514            totalFixed += m_layoutStruct[i].effectiveMaxLogicalWidth;
    533515            // fall through
    534516            break;
    535517        case Auto:
    536518        case Static:
    537             if (m_layoutStruct[i].emptyCellsOnly) 
    538                 numAutoEmptyCellsOnly++;           
     519            if (m_layoutStruct[i].emptyCellsOnly)
     520                numAutoEmptyCellsOnly++;
    539521            else {
    540522                numAuto++;
    541                 totalAuto += m_layoutStruct[i].effMaxWidth;
    542                 allocAuto += w;
     523                totalAuto += m_layoutStruct[i].effectiveMaxLogicalWidth;
     524                allocAuto += cellLogicalWidth;
    543525            }
    544526            break;
     
    550532    // allocate width to percent cols
    551533    if (available > 0 && havePercent) {
    552         for (int i = 0; i < nEffCols; i++) {
    553             Length &width = m_layoutStruct[i].effWidth;
    554             if (width.isPercent()) {
    555                 int w = max(int(m_layoutStruct[i].effMinWidth), width.calcMinValue(tableWidth));
    556                 available += m_layoutStruct[i].calcWidth - w;
    557                 m_layoutStruct[i].calcWidth = w;
     534        for (size_t i = 0; i < nEffCols; ++i) {
     535            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     536            if (logicalWidth.isPercent()) {
     537                int cellLogicalWidth = max(m_layoutStruct[i].effectiveMinLogicalWidth, logicalWidth.calcMinValue(tableLogicalWidth));
     538                available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth;
     539                m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
    558540            }
    559541        }
    560542        if (totalPercent > 100 * percentScaleFactor) {
    561543            // remove overallocated space from the last columns
    562             int excess = tableWidth*(totalPercent - 100 * percentScaleFactor) / (100 * percentScaleFactor);
    563             for (int i = nEffCols-1; i >= 0; i--) {
    564                 if (m_layoutStruct[i].effWidth.isPercent()) {
    565                     int w = m_layoutStruct[i].calcWidth;
    566                     int reduction = min(w,  excess);
     544            int excess = tableLogicalWidth * (totalPercent - 100 * percentScaleFactor) / (100 * percentScaleFactor);
     545            for (int i = nEffCols - 1; i >= 0; --i) {
     546                if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) {
     547                    int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidth;
     548                    int reduction = min(cellLogicalWidth,  excess);
    567549                    // the lines below might look inconsistent, but that's the way it's handled in mozilla
    568550                    excess -= reduction;
    569                     int newWidth = max(static_cast<int>(m_layoutStruct[i].effMinWidth), w - reduction);
    570                     available += w - newWidth;
    571                     m_layoutStruct[i].calcWidth = newWidth;
     551                    int newLogicalWidth = max(m_layoutStruct[i].effectiveMinLogicalWidth, cellLogicalWidth - reduction);
     552                    available += cellLogicalWidth - newLogicalWidth;
     553                    m_layoutStruct[i].computedLogicalWidth = newLogicalWidth;
    572554                }
    573555            }
     
    577559    // then allocate width to fixed cols
    578560    if (available > 0) {
    579         for (int i = 0; i < nEffCols; ++i) {
    580             Length &width = m_layoutStruct[i].effWidth;
    581             if (width.isFixed() && width.value() > m_layoutStruct[i].calcWidth) {
    582                 available += m_layoutStruct[i].calcWidth - width.value();
    583                 m_layoutStruct[i].calcWidth = width.value();
     561        for (size_t i = 0; i < nEffCols; ++i) {
     562            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     563            if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[i].computedLogicalWidth) {
     564                available += m_layoutStruct[i].computedLogicalWidth - logicalWidth.value();
     565                m_layoutStruct[i].computedLogicalWidth = logicalWidth.value();
    584566            }
    585567        }
     
    588570    // now satisfy relative
    589571    if (available > 0) {
    590         for (int i = 0; i < nEffCols; i++) {
    591             Length &width = m_layoutStruct[i].effWidth;
    592             if (width.isRelative() && width.value() != 0) {
     572        for (size_t i = 0; i < nEffCols; ++i) {
     573            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     574            if (logicalWidth.isRelative() && logicalWidth.value() != 0) {
    593575                // width=0* gets effMinWidth.
    594                 int w = width.value() * tableWidth / totalRelative;
    595                 available += m_layoutStruct[i].calcWidth - w;
    596                 m_layoutStruct[i].calcWidth = w;
     576                int cellLogicalWidth = logicalWidth.value() * tableLogicalWidth / totalRelative;
     577                available += m_layoutStruct[i].computedLogicalWidth - cellLogicalWidth;
     578                m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
    597579            }
    598580        }
     
    602584    if (available > 0 && numAuto) {
    603585        available += allocAuto; // this gets redistributed
    604         for (int i = 0; i < nEffCols; i++) {
    605             Length &width = m_layoutStruct[i].effWidth;
    606             if (width.isAuto() && totalAuto != 0 && !m_layoutStruct[i].emptyCellsOnly) {
    607                 int w = max(m_layoutStruct[i].calcWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effMaxWidth) / totalAuto));
    608                 available -= w;
    609                 totalAuto -= m_layoutStruct[i].effMaxWidth;
    610                 m_layoutStruct[i].calcWidth = w;
     586        for (size_t i = 0; i < nEffCols; ++i) {
     587            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     588            if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCellsOnly) {
     589                int cellLogicalWidth = max(m_layoutStruct[i].computedLogicalWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalAuto));
     590                available -= cellLogicalWidth;
     591                totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth;
     592                m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth;
    611593            }
    612594        }
     
    615597    // spread over fixed columns
    616598    if (available > 0 && numFixed) {
    617         // still have some width to spread, distribute to fixed columns
    618         for (int i = 0; i < nEffCols; i++) {
    619             Length &width = m_layoutStruct[i].effWidth;
    620             if (width.isFixed()) {
    621                 int w = static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effMaxWidth) / totalFixed);
    622                 available -= w;
    623                 totalFixed -= m_layoutStruct[i].effMaxWidth;
    624                 m_layoutStruct[i].calcWidth += w;
     599        for (size_t i = 0; i < nEffCols; ++i) {
     600            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     601            if (logicalWidth.isFixed()) {
     602                int cellLogicalWidth = static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effectiveMaxLogicalWidth) / totalFixed);
     603                available -= cellLogicalWidth;
     604                totalFixed -= m_layoutStruct[i].effectiveMaxLogicalWidth;
     605                m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
    625606            }
    626607        }
     
    629610    // spread over percent colums
    630611    if (available > 0 && m_hasPercent && totalPercent < 100 * percentScaleFactor) {
    631         // still have some width to spread, distribute weighted to percent columns
    632         for (int i = 0; i < nEffCols; i++) {
    633             Length &width = m_layoutStruct[i].effWidth;
    634             if (width.isPercent()) {
    635                 int w = available * width.rawValue() / totalPercent;
    636                 available -= w;
    637                 totalPercent -= width.rawValue();
    638                 m_layoutStruct[i].calcWidth += w;
    639                 if (!available || !totalPercent) break;
     612        for (size_t i = 0; i < nEffCols; ++i) {
     613            Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     614            if (logicalWidth.isPercent()) {
     615                int cellLogicalWidth = available * logicalWidth.rawValue() / totalPercent;
     616                available -= cellLogicalWidth;
     617                totalPercent -= logicalWidth.rawValue();
     618                m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
     619                if (!available || !totalPercent)
     620                    break;
    640621            }
    641622        }
     
    646627        int total = nEffCols - numAutoEmptyCellsOnly;
    647628        // still have some width to spread
    648         int i = nEffCols;
    649         while (i--) {
     629        for (int i = nEffCols - 1; i >= 0; --i) {
    650630            // variable columns with empty cells only don't get any width
    651             if (m_layoutStruct[i].effWidth.isAuto() && m_layoutStruct[i].emptyCellsOnly)
     631            if (m_layoutStruct[i].effectiveLogicalWidth.isAuto() && m_layoutStruct[i].emptyCellsOnly)
    652632                continue;
    653             int w = available / total;
    654             available -= w;
     633            int cellLogicalWidth = available / total;
     634            available -= cellLogicalWidth;
    655635            total--;
    656             m_layoutStruct[i].calcWidth += w;
     636            m_layoutStruct[i].computedLogicalWidth += cellLogicalWidth;
    657637        }
    658638    }
     
    668648        // This is basically the reverse of how we grew the cells.
    669649        if (available < 0) {
    670             int mw = 0;
    671             for (int i = nEffCols-1; i >= 0; i--) {
    672                 Length &width = m_layoutStruct[i].effWidth;
    673                 if (width.isAuto())
    674                     mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;
     650            int logicalWidthBeyondMin = 0;
     651            for (int i = nEffCols - 1; i >= 0; --i) {
     652                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     653                if (logicalWidth.isAuto())
     654                    logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
    675655            }
    676656           
    677             for (int i = nEffCols-1; i >= 0 && mw > 0; i--) {
    678                 Length &width = m_layoutStruct[i].effWidth;
    679                 if (width.isAuto()) {
    680                     int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth;
    681                     int reduce = available * minMaxDiff / mw;
    682                     m_layoutStruct[i].calcWidth += reduce;
     657            for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) {
     658                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     659                if (logicalWidth.isAuto()) {
     660                    int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
     661                    int reduce = available * minMaxDiff / logicalWidthBeyondMin;
     662                    m_layoutStruct[i].computedLogicalWidth += reduce;
    683663                    available -= reduce;
    684                     mw -= minMaxDiff;
     664                    logicalWidthBeyondMin -= minMaxDiff;
    685665                    if (available >= 0)
    686666                        break;
     
    690670
    691671        if (available < 0) {
    692             int mw = 0;
    693             for (int i = nEffCols-1; i >= 0; i--) {
    694                 Length& width = m_layoutStruct[i].effWidth;
    695                 if (width.isRelative())
    696                     mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;
     672            int logicalWidthBeyondMin = 0;
     673            for (int i = nEffCols - 1; i >= 0; --i) {
     674                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     675                if (logicalWidth.isRelative())
     676                    logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
    697677            }
    698678           
    699             for (int i = nEffCols-1; i >= 0 && mw > 0; i--) {
    700                 Length& width = m_layoutStruct[i].effWidth;
    701                 if (width.isRelative()) {
    702                     int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth;
    703                     int reduce = available * minMaxDiff / mw;
    704                     m_layoutStruct[i].calcWidth += reduce;
     679            for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) {
     680                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     681                if (logicalWidth.isRelative()) {
     682                    int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
     683                    int reduce = available * minMaxDiff / logicalWidthBeyondMin;
     684                    m_layoutStruct[i].computedLogicalWidth += reduce;
    705685                    available -= reduce;
    706                     mw -= minMaxDiff;
     686                    logicalWidthBeyondMin -= minMaxDiff;
    707687                    if (available >= 0)
    708688                        break;
     
    712692
    713693        if (available < 0) {
    714             int mw = 0;
    715             for (int i = nEffCols-1; i >= 0; i--) {
    716                 Length& width = m_layoutStruct[i].effWidth;
    717                 if (width.isFixed())
    718                     mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;
     694            int logicalWidthBeyondMin = 0;
     695            for (int i = nEffCols - 1; i >= 0; --i) {
     696                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     697                if (logicalWidth.isFixed())
     698                    logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
    719699            }
    720700           
    721             for (int i = nEffCols-1; i >= 0 && mw > 0; i--) {
    722                 Length& width = m_layoutStruct[i].effWidth;
    723                 if (width.isFixed()) {
    724                     int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth;
    725                     int reduce = available * minMaxDiff / mw;
    726                     m_layoutStruct[i].calcWidth += reduce;
     701            for (int i = nEffCols - 1; i >= 0 && logicalWidthBeyondMin > 0; --i) {
     702                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     703                if (logicalWidth.isFixed()) {
     704                    int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
     705                    int reduce = available * minMaxDiff / logicalWidthBeyondMin;
     706                    m_layoutStruct[i].computedLogicalWidth += reduce;
    727707                    available -= reduce;
    728                     mw -= minMaxDiff;
     708                    logicalWidthBeyondMin -= minMaxDiff;
    729709                    if (available >= 0)
    730710                        break;
     
    734714
    735715        if (available < 0) {
    736             int mw = 0;
    737             for (int i = nEffCols-1; i >= 0; i--) {
    738                 Length& width = m_layoutStruct[i].effWidth;
    739                 if (width.isPercent())
    740                     mw += m_layoutStruct[i].calcWidth - m_layoutStruct[i].effMinWidth;
     716            int logicalWidthBeyondMin = 0;
     717            for (int i = nEffCols - 1; i >= 0; --i) {
     718                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     719                if (logicalWidth.isPercent())
     720                    logicalWidthBeyondMin += m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
    741721            }
    742722           
    743             for (int i = nEffCols-1; i >= 0 && mw > 0; i--) {
    744                 Length& width = m_layoutStruct[i].effWidth;
    745                 if (width.isPercent()) {
    746                     int minMaxDiff = m_layoutStruct[i].calcWidth-m_layoutStruct[i].effMinWidth;
    747                     int reduce = available * minMaxDiff / mw;
    748                     m_layoutStruct[i].calcWidth += reduce;
     723            for (int i = nEffCols-1; i >= 0 && logicalWidthBeyondMin > 0; i--) {
     724                Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
     725                if (logicalWidth.isPercent()) {
     726                    int minMaxDiff = m_layoutStruct[i].computedLogicalWidth - m_layoutStruct[i].effectiveMinLogicalWidth;
     727                    int reduce = available * minMaxDiff / logicalWidthBeyondMin;
     728                    m_layoutStruct[i].computedLogicalWidth += reduce;
    749729                    available -= reduce;
    750                     mw -= minMaxDiff;
     730                    logicalWidthBeyondMin -= minMaxDiff;
    751731                    if (available >= 0)
    752732                        break;
     
    757737
    758738    int pos = 0;
    759     for (int i = 0; i < nEffCols; i++) {
     739    for (size_t i = 0; i < nEffCols; ++i) {
    760740        m_table->columnPositions()[i] = pos;
    761         pos += m_layoutStruct[i].calcWidth + m_table->hBorderSpacing();
     741        pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing();
    762742    }
    763743    m_table->columnPositions()[m_table->columnPositions().size() - 1] = pos;
  • trunk/WebCore/rendering/AutoTableLayout.h

    r71138 r71262  
    3939    virtual void layout();
    4040
    41 protected:
     41private:
    4242    void fullRecalc();
    4343    void recalcColumn(int effCol);
    4444
    45     int calcEffectiveWidth();
     45    int calcEffectiveLogicalWidth();
    4646
    4747    void insertSpanCell(RenderTableCell*);
     
    4949    struct Layout {
    5050        Layout()
    51             : minWidth(0)
    52             , maxWidth(0)
    53             , effMinWidth(0)
    54             , effMaxWidth(0)
    55             , calcWidth(0)
    56             , emptyCellsOnly(true) {}
    57         Length width;
    58         Length effWidth;
    59         int minWidth;
    60         int maxWidth;
    61         int effMinWidth;
    62         int effMaxWidth;
    63         int calcWidth;
     51            : minLogicalWidth(0)
     52            , maxLogicalWidth(0)
     53            , effectiveMinLogicalWidth(0)
     54            , effectiveMaxLogicalWidth(0)
     55            , computedLogicalWidth(0)
     56            , emptyCellsOnly(true)
     57        {
     58        }
     59
     60        Length logicalWidth;
     61        Length effectiveLogicalWidth;
     62        int minLogicalWidth;
     63        int maxLogicalWidth;
     64        int effectiveMinLogicalWidth;
     65        int effectiveMaxLogicalWidth;
     66        int computedLogicalWidth;
    6467        bool emptyCellsOnly;
    6568    };
     
    6871    Vector<RenderTableCell*, 4> m_spanCells;
    6972    bool m_hasPercent : 1;
    70     mutable bool m_effWidthDirty : 1;
     73    mutable bool m_effectiveLogicalWidthDirty : 1;
    7174};
    7275
  • trunk/WebCore/rendering/FixedTableLayout.cpp

    r71251 r71262  
    22 * Copyright (C) 2002 Lars Knoll (knoll@kde.org)
    33 *           (C) 2002 Dirk Mueller (mueller@kde.org)
    4  * Copyright (C) 2003, 2006 Apple Computer, Inc.
     4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc.
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    9090    int currentEffectiveColumn = 0;
    9191    Length grpWidth;
    92     while (child) {
    93         if (child->isTableCol()) {
    94             RenderTableCol* col = toRenderTableCol(child);
    95             if (col->firstChild())
    96                 grpWidth = col->style()->width();
    97             else {
    98                 Length w = col->style()->width();
    99                 if (w.isAuto())
    100                     w = grpWidth;
    101                 int effWidth = 0;
    102                 if (w.isFixed() && w.value() > 0)
    103                     effWidth = w.value();
    104 
    105                 int span = col->span();
    106                 while (span) {
    107                     int spanInCurrentEffectiveColumn;
    108                     if (currentEffectiveColumn >= nEffCols) {
    109                         m_table->appendColumn(span);
     92    while (child && child->isTableCol()) {
     93        RenderTableCol* col = toRenderTableCol(child);
     94        if (col->firstChild())
     95            grpWidth = col->style()->logicalWidth();
     96        else {
     97            Length w = col->style()->logicalWidth();
     98            if (w.isAuto())
     99                w = grpWidth;
     100            int effWidth = 0;
     101            if (w.isFixed() && w.value() > 0)
     102                effWidth = w.value();
     103
     104            int span = col->span();
     105            while (span) {
     106                int spanInCurrentEffectiveColumn;
     107                if (currentEffectiveColumn >= nEffCols) {
     108                    m_table->appendColumn(span);
     109                    nEffCols++;
     110                    m_width.append(Length());
     111                    spanInCurrentEffectiveColumn = span;
     112                } else {
     113                    if (span < m_table->spanOfEffCol(currentEffectiveColumn)) {
     114                        m_table->splitColumn(currentEffectiveColumn, span);
    110115                        nEffCols++;
    111116                        m_width.append(Length());
    112                         spanInCurrentEffectiveColumn = span;
    113                     } else {
    114                         if (span < m_table->spanOfEffCol(currentEffectiveColumn)) {
    115                             m_table->splitColumn(currentEffectiveColumn, span);
    116                             nEffCols++;
    117                             m_width.append(Length());
    118                         }
    119                         spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn);
    120117                    }
    121                     if ((w.isFixed() || w.isPercent()) && w.isPositive()) {
    122                         m_width[currentEffectiveColumn].setRawValue(w.type(), w.rawValue() * spanInCurrentEffectiveColumn);
    123                         usedWidth += effWidth * spanInCurrentEffectiveColumn;
    124                     }
    125                     span -= spanInCurrentEffectiveColumn;
    126                     currentEffectiveColumn++;
    127                 }
    128             }
    129             toRenderTableCol(child)->computePreferredLogicalWidths();
    130         } else
    131             break;
     118                    spanInCurrentEffectiveColumn = m_table->spanOfEffCol(currentEffectiveColumn);
     119                }
     120                if ((w.isFixed() || w.isPercent()) && w.isPositive()) {
     121                    m_width[currentEffectiveColumn].setRawValue(w.type(), w.rawValue() * spanInCurrentEffectiveColumn);
     122                    usedWidth += effWidth * spanInCurrentEffectiveColumn;
     123                }
     124                span -= spanInCurrentEffectiveColumn;
     125                currentEffectiveColumn++;
     126            }
     127        }
     128        col->computePreferredLogicalWidths();
    132129
    133130        RenderObject* next = child->firstChild();
     
    202199    //
    203200    // The maximum width is max(minWidth, tableWidth).
    204     int bs = m_table->bordersPaddingAndSpacing();
    205    
    206     int tableWidth = m_table->style()->width().isFixed() ? m_table->style()->width().value() - bs : 0;
    207     int mw = calcWidthArray(tableWidth) + bs;
    208 
    209     minWidth = max(mw, tableWidth);
     201    int bordersPaddingAndSpacing = m_table->bordersPaddingAndSpacingInRowDirection();
     202
     203    int tableLogicalWidth = m_table->style()->logicalWidth().isFixed() ? m_table->style()->logicalWidth().value() - bordersPaddingAndSpacing : 0;
     204    int mw = calcWidthArray(tableLogicalWidth) + bordersPaddingAndSpacing;
     205
     206    minWidth = max(mw, tableLogicalWidth);
    210207    maxWidth = minWidth;
    211208
     
    224221    // We can achieve this effect by making the maxwidth of fixed tables with percentage
    225222    // widths be infinite.
    226     if (m_table->document()->inQuirksMode() && m_table->style()->width().isPercent()
    227         && maxWidth < TABLE_MAX_WIDTH)
     223    if (m_table->document()->inQuirksMode() && m_table->style()->logicalWidth().isPercent() && maxWidth < TABLE_MAX_WIDTH)
    228224        maxWidth = TABLE_MAX_WIDTH;
    229225}
     
    231227void FixedTableLayout::layout()
    232228{
    233     int tableWidth = m_table->width() - m_table->bordersPaddingAndSpacing();
     229    int tableLogicalWidth = m_table->logicalWidth() - m_table->bordersPaddingAndSpacingInRowDirection();
    234230    int nEffCols = m_table->numEffCols();
    235231    Vector<int> calcWidth(nEffCols, 0);
     
    250246            totalFixedWidth += calcWidth[i];
    251247        } else if (m_width[i].isPercent()) {
    252             calcWidth[i] = m_width[i].calcValue(tableWidth);
     248            calcWidth[i] = m_width[i].calcValue(tableLogicalWidth);
    253249            totalPercentWidth += calcWidth[i];
    254250            totalRawPercent += m_width[i].rawValue();
     
    261257    int hspacing = m_table->hBorderSpacing();
    262258    int totalWidth = totalFixedWidth + totalPercentWidth;
    263     if (!numAuto || totalWidth > tableWidth) {
     259    if (!numAuto || totalWidth > tableLogicalWidth) {
    264260        // If there are no auto columns, or if the total is too wide, take
    265261        // what we have and scale it to fit as necessary.
    266         if (totalWidth != tableWidth) {
     262        if (totalWidth != tableLogicalWidth) {
    267263            // Fixed widths only scale up
    268             if (totalFixedWidth && totalWidth < tableWidth) {
     264            if (totalFixedWidth && totalWidth < tableLogicalWidth) {
    269265                totalFixedWidth = 0;
    270266                for (int i = 0; i < nEffCols; i++) {
    271267                    if (m_width[i].isFixed()) {
    272                         calcWidth[i] = calcWidth[i] * tableWidth / totalWidth;
     268                        calcWidth[i] = calcWidth[i] * tableLogicalWidth / totalWidth;
    273269                        totalFixedWidth += calcWidth[i];
    274270                    }
     
    279275                for (int i = 0; i < nEffCols; i++) {
    280276                    if (m_width[i].isPercent()) {
    281                         calcWidth[i] = m_width[i].rawValue() * (tableWidth - totalFixedWidth) / totalRawPercent;
     277                        calcWidth[i] = m_width[i].rawValue() * (tableLogicalWidth - totalFixedWidth) / totalRawPercent;
    282278                        totalPercentWidth += calcWidth[i];
    283279                    }
     
    288284    } else {
    289285        // Divide the remaining width among the auto columns.
    290         int remainingWidth = tableWidth - totalFixedWidth - totalPercentWidth - hspacing * (autoSpan - numAuto);
     286        int remainingWidth = tableLogicalWidth - totalFixedWidth - totalPercentWidth - hspacing * (autoSpan - numAuto);
    291287        int lastAuto = 0;
    292288        for (int i = 0; i < nEffCols; i++) {
     
    306302        if (remainingWidth)
    307303            calcWidth[lastAuto] += remainingWidth;
    308         totalWidth = tableWidth;
    309     }
    310 
    311     if (totalWidth < tableWidth) {
     304        totalWidth = tableLogicalWidth;
     305    }
     306
     307    if (totalWidth < tableLogicalWidth) {
    312308        // Spread extra space over columns.
    313         int remainingWidth = tableWidth - totalWidth;
     309        int remainingWidth = tableLogicalWidth - totalWidth;
    314310        int total = nEffCols;
    315311        while (total) {
  • trunk/WebCore/rendering/FixedTableLayout.h

    r68276 r71262  
    3737    virtual void layout();
    3838
    39 protected:
     39private:
    4040    int calcWidthArray(int tableWidth);
    4141
  • trunk/WebCore/rendering/RenderTable.h

    r69437 r71262  
    109109    }
    110110
    111     int bordersPaddingAndSpacing() const
     111    int bordersPaddingAndSpacingInRowDirection() const
    112112    {
    113113        return borderLeft() + borderRight() +
Note: See TracChangeset for help on using the changeset viewer.