Changeset 13366 in webkit


Ignore:
Timestamp:
Mar 17, 2006 5:01:06 PM (18 years ago)
Author:
hyatt
Message:

Fix for 7837, make opacity work with table rows. Make transparent backgrounds
stack properly in cells (so that the layers behind can show through like they
should).

Reviewed by beth

  • rendering/RenderTableCell.cpp: (WebCore::RenderTableCell::requiresLayer): (WebCore::RenderTableCell::paintBackgroundsBehindCell): (WebCore::RenderTableCell::paintBoxDecorations):
  • rendering/RenderTableCell.h:
  • rendering/RenderTableRow.cpp: (WebCore::RenderTableRow::paint):
  • rendering/RenderTableRow.h: (WebCore::RenderTableRow::requiresLayer):
  • rendering/RenderTableSection.cpp: (WebCore::RenderTableSection::paint):
  • rendering/render_layer.cpp: (WebCore::RenderLayer::updateLayerPosition): (WebCore::RenderLayer::isTransparent): (WebCore::RenderLayer::transparentAncestor): (WebCore::RenderLayer::beginTransparencyLayers): (WebCore::RenderLayer::paintLayer): (WebCore::RenderLayer::absoluteBoundingBox):
  • rendering/render_object.cpp: (WebCore::RenderObject::requiresLayer):
  • rendering/render_object.h: (WebCore::RenderObject::isTransparent): (WebCore::RenderObject::opacity):
Location:
trunk/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r13364 r13366  
     12006-03-17  David Hyatt  <hyatt@apple.com>
     2
     3        Fix for 7837, make opacity work with table rows.  Make transparent backgrounds
     4        stack properly in cells (so that the layers behind can show through like they
     5        should).
     6
     7        Reviewed by beth
     8
     9        * rendering/RenderTableCell.cpp:
     10        (WebCore::RenderTableCell::requiresLayer):
     11        (WebCore::RenderTableCell::paintBackgroundsBehindCell):
     12        (WebCore::RenderTableCell::paintBoxDecorations):
     13        * rendering/RenderTableCell.h:
     14        * rendering/RenderTableRow.cpp:
     15        (WebCore::RenderTableRow::paint):
     16        * rendering/RenderTableRow.h:
     17        (WebCore::RenderTableRow::requiresLayer):
     18        * rendering/RenderTableSection.cpp:
     19        (WebCore::RenderTableSection::paint):
     20        * rendering/render_layer.cpp:
     21        (WebCore::RenderLayer::updateLayerPosition):
     22        (WebCore::RenderLayer::isTransparent):
     23        (WebCore::RenderLayer::transparentAncestor):
     24        (WebCore::RenderLayer::beginTransparencyLayers):
     25        (WebCore::RenderLayer::paintLayer):
     26        (WebCore::RenderLayer::absoluteBoundingBox):
     27        * rendering/render_object.cpp:
     28        (WebCore::RenderObject::requiresLayer):
     29        * rendering/render_object.h:
     30        (WebCore::RenderObject::isTransparent):
     31        (WebCore::RenderObject::opacity):
     32
    1332006-03-17  Maciej Stachowiak  <mjs@apple.com>
    234
  • trunk/WebCore/rendering/RenderTableCell.cpp

    r13346 r13366  
    173173}
    174174
    175 bool RenderTableCell::requiresLayer() {
    176     return isPositioned() || style()->opacity() < 1.0f || hasOverflowClip();
     175bool RenderTableCell::requiresLayer()
     176{
     177    return isPositioned() || isTransparent() || hasOverflowClip();
    177178}
    178179
     
    694695}
    695696
    696 void RenderTableCell::paintBoxDecorations(PaintInfo& i, int _tx, int _ty)
    697 {
     697void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& i, int _tx, int _ty, RenderObject* backgroundObject)
     698{
     699    if (!backgroundObject)
     700        return;
     701
    698702    RenderTable* tableElt = table();
    699703    if (!tableElt->collapseBorders() && style()->emptyCells() == HIDE && !firstChild())
    700704        return;
    701    
     705
     706    if (backgroundObject != this) {
     707        _tx += m_x;
     708        _ty += m_y + _topExtra;
     709    }
     710
    702711    int w = width();
    703712    int h = height() + borderTopExtra() + borderBottomExtra();
    704713    _ty -= borderTopExtra();
    705 
    706     Color c = style()->backgroundColor();
    707     if (!c.isValid() && parent()) // take from row
    708         c = parent()->style()->backgroundColor();
    709     if (!c.isValid() && parent() && parent()->parent()) // take from rowgroup
    710         c = parent()->parent()->style()->backgroundColor();
    711     if (!c.isValid()) {
    712         // see if we have a col or colgroup for this
    713         RenderTableCol *col = table()->colElement(_col);
    714         if (col) {
    715             c = col->style()->backgroundColor();
    716             if (!c.isValid()) {
    717                 // try column group
    718                 RenderStyle *style = col->parent()->style();
    719                 if (style->display() == TABLE_COLUMN_GROUP)
    720                     c = style->backgroundColor();
    721             }
    722         }
    723     }
    724 
    725     // FIXME: This code is just plain wrong.  Rows and columns should paint their backgrounds
    726     // independent from the cell.
    727     // ### get offsets right in case the bgimage is inherited.
    728     const BackgroundLayer* bgLayer = style()->backgroundLayers();
    729     if (!bgLayer->hasImage() && parent())
    730         bgLayer = parent()->style()->backgroundLayers();
    731     if (!bgLayer->hasImage() && parent() && parent()->parent())
    732         bgLayer = parent()->parent()->style()->backgroundLayers();
    733     if (!bgLayer->hasImage()) {
    734         // see if we have a col or colgroup for this
    735         RenderTableCol* col = table()->colElement(_col);
    736         if (col) {
    737             bgLayer = col->style()->backgroundLayers();
    738             if (!bgLayer->hasImage()) {
    739                 // try column group
    740                 RenderStyle *style = col->parent()->style();
    741                 if (style->display() == TABLE_COLUMN_GROUP)
    742                     bgLayer = style->backgroundLayers();
    743             }
    744         }
    745     }
    746 
     714   
    747715    int my = kMax(_ty, i.r.y());
    748716    int end = kMin(i.r.bottom(), _ty + h);
    749717    int mh = end - my;
     718   
     719    Color c = backgroundObject->style()->backgroundColor();
     720    const BackgroundLayer* bgLayer = backgroundObject->style()->backgroundLayers();
    750721
    751722    if (bgLayer->hasImage() || c.isValid()) {
    752         // We have to clip here because the backround would paint
    753         // on top of the borders otherwise.
    754         if (m_layer && tableElt->collapseBorders()) {
     723        // We have to clip here because the background would paint
     724        // on top of the borders otherwise.  This only matters for cells and rows.
     725        bool hasLayer = backgroundObject->layer() && (backgroundObject == this || backgroundObject == parent());
     726        if (hasLayer && tableElt->collapseBorders()) {
    755727            IntRect clipRect(_tx + borderLeft(), _ty + borderTop(),
    756728                w - borderLeft() - borderRight(), h - borderTop() - borderBottom());
     
    759731        }
    760732        paintBackground(i.p, c, bgLayer, my, mh, _tx, _ty, w, h);
    761         if (m_layer && tableElt->collapseBorders())
     733        if (hasLayer && tableElt->collapseBorders())
    762734            i.p->restore();
    763735    }
     736}
     737
     738void RenderTableCell::paintBoxDecorations(PaintInfo& i, int _tx, int _ty)
     739{
     740    RenderTable* tableElt = table();
     741    if (!tableElt->collapseBorders() && style()->emptyCells() == HIDE && !firstChild())
     742        return;
     743 
     744    // Paint our cell background.
     745    paintBackgroundsBehindCell(i, _tx, _ty, this);
     746
     747    int w = width();
     748    int h = height() + borderTopExtra() + borderBottomExtra();
     749    _ty -= borderTopExtra();
    764750
    765751    if (style()->hasBorder() && !tableElt->collapseBorders())
  • trunk/WebCore/rendering/RenderTableCell.h

    r13067 r13366  
    6161
    6262    virtual bool requiresLayer();
     63
    6364    virtual void calcMinMaxWidth();
    6465    virtual void calcWidth();
     
    108109    virtual IntRect getAbsoluteRepaintRect();
    109110   
     111    void paintBackgroundsBehindCell(PaintInfo&, int tx, int ty, RenderObject* backgroundObject);
     112
    110113protected:
    111114    virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
    112    
     115
    113116    int _row;
    114117    int _col;
  • trunk/WebCore/rendering/RenderTableRow.cpp

    r13346 r13366  
    151151}
    152152
     153void RenderTableRow::paint(PaintInfo& i, int tx, int ty)
     154{
     155    assert(m_layer);
     156    if (!m_layer)
     157        return;
     158
     159    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
     160        if (child->isTableCell()) {
     161            // Paint the row background behind the cell.
     162            if (i.phase == PaintActionBlockBackground || i.phase == PaintActionChildBlockBackground) {
     163                RenderTableCell* cell = static_cast<RenderTableCell*>(child);
     164                cell->paintBackgroundsBehindCell(i, tx, ty, this);
     165            }
     166            if (!child->layer())
     167                child->paint(i, tx, ty);
     168        }
     169    }
    153170}
     171
     172}
  • trunk/WebCore/rendering/RenderTableRow.h

    r13346 r13366  
    4848    virtual bool nodeAtPoint(NodeInfo& info, int x, int y, int tx, int ty, HitTestAction action);
    4949
    50     // FIXME: We can't support things like opacity on table rows because they have no dimensions.  This can be removed when
    51     // table rows really work right.
    52     virtual bool requiresLayer() { return false; }
     50    // The only time rows get a layer is when they have transparency.
     51    virtual bool requiresLayer() { return isTransparent(); }
     52
     53    virtual void paint(PaintInfo& i, int tx, int ty);
    5354
    5455    RenderTable* table() const { return static_cast<RenderTable*>(parent()->parent()); }
  • trunk/WebCore/rendering/RenderTableSection.cpp

    r13346 r13366  
    3030#include "RenderTableCell.h"
    3131#include "RenderTableRow.h"
     32#include "RenderTableCol.h"
    3233#include "DocumentImpl.h"
    3334#include "htmlnames.h"
     
    650651                CellStruct current = cellAt(r, c);
    651652                RenderTableCell *cell = current.cell;
    652                
    653                 if (!cell || (cell->layer() && i.phase != PaintActionCollapsedTableBorders))
    654                     continue;
    655                
     653                   
    656654                // Cells must always paint in the order in which they appear taking into account
    657655                // their upper left originating row/column.  For cells with rowspans, avoid repainting
    658656                // if we've already seen the cell.
    659                 if (r > startrow && (cellAt(r-1, c).cell == cell))
     657                if (!cell || (r > startrow && (cellAt(r-1, c).cell == cell)))
    660658                    continue;
    661659
    662                 cell->paint(i, tx, ty);
     660                if (paintAction == PaintActionBlockBackground || paintAction == PaintActionChildBlockBackground) {
     661                    // We need to handle painting a stack of backgrounds.  This stack (from bottom to top) consists of
     662                    // the column group, column, row group, row, and then the cell.
     663                    RenderObject* col = table()->colElement(c);
     664                    RenderObject* colGroup = 0;
     665                    if (col) {
     666                        RenderStyle *style = col->parent()->style();
     667                        if (style->display() == TABLE_COLUMN_GROUP)
     668                            colGroup = col->parent();
     669                    }
     670                    RenderObject* row = cell->parent();
     671                   
     672                    // Column groups and columns first.
     673                    // FIXME: Columns and column groups do not currently support opacity, and they are being painted "too late" in
     674                    // the stack, since we have already opened a transparency layer (potentially) for the table row group.
     675                    // Note that we deliberately ignore whether or not the cell has a layer, since these backgrounds paint "behind" the
     676                    // cell.
     677                    cell->paintBackgroundsBehindCell(i, tx, ty, colGroup);
     678                    cell->paintBackgroundsBehindCell(i, tx, ty, col);
     679                   
     680                    // Paint the row group next.
     681                    cell->paintBackgroundsBehindCell(i, tx, ty, this);
     682                   
     683                    // Paint the row next, but only if it doesn't have a layer.  If a row has a layer, it will be responsible for
     684                    // painting the row background for the cell.
     685                    if (!row->layer())
     686                        cell->paintBackgroundsBehindCell(i, tx, ty, row);
     687                }
     688
     689                if ((!cell->layer() && !cell->parent()->layer()) || i.phase == PaintActionCollapsedTableBorders)
     690                    cell->paint(i, tx, ty);
    663691            }
    664692        }
  • trunk/WebCore/rendering/render_layer.cpp

    r13347 r13366  
    238238        }
    239239        y += curr->borderTopExtra();
     240        if (curr->isTableRow()) {
     241            // Put ourselves into the row coordinate space.
     242            x -= curr->xPos();
     243            y -= curr->yPos();
     244        }
    240245    }
    241246
     
    328333        return false;
    329334#endif
    330     return m_object->style()->opacity() < 1.0f;
     335    return m_object->isTransparent();
    331336}
    332337
     
    335340{
    336341    RenderLayer* curr = parent();
    337     for ( ; curr && curr->m_object->style()->opacity() == 1.0f; curr = curr->parent());
     342    for ( ; curr && !curr->isTransparent(); curr = curr->parent());
    338343    return curr;
    339344}
     
    372377        p->save();
    373378        p->addClip(clipRect);
    374         p->beginTransparencyLayer(renderer()->style()->opacity());
     379        p->beginTransparencyLayer(renderer()->opacity());
    375380    }
    376381}
     
    10841089    // so it will be tested against as we decend through the renderers.
    10851090    RenderObject *paintingRootForRenderer = 0;
    1086     if (paintingRoot && !m_object->hasAncestor(paintingRoot)) {
     1091    if (paintingRoot && !m_object->hasAncestor(paintingRoot))
    10871092        paintingRootForRenderer = paintingRoot;
    1088     }
    10891093   
    10901094    // We want to paint our layer, but only if we intersect the damage rect.
     
    14021406            left = kMin(left, curr->xPos());
    14031407        result = IntRect(m_x + left, m_y + (top - renderer()->yPos()), width(), bottom - top);
     1408    } else if (renderer()->isTableRow()) {
     1409        // Our bounding box is just the union of all of our cells' border/overflow rects.
     1410        for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
     1411            if (child->isTableCell()) {
     1412                IntRect bbox = child->borderBox();
     1413                bbox.move(0, child->borderTopExtra());
     1414                result.unite(bbox);
     1415                IntRect overflowRect = renderer()->overflowRect(false);
     1416                overflowRect.move(0, child->borderTopExtra());
     1417                if (bbox != overflowRect)
     1418                    result.unite(overflowRect);
     1419            }
     1420        }
     1421        result.move(m_x, m_y);
    14041422    } else {
    14051423        IntRect bbox = renderer()->borderBox();
  • trunk/WebCore/rendering/render_object.cpp

    r13346 r13366  
    529529bool RenderObject::requiresLayer()
    530530{
    531     return isRoot() || isPositioned() || isRelPositioned() || style()->opacity() < 1.0f ||
    532            hasOverflowClip();
     531    return isRoot() || isPositioned() || isRelPositioned() || isTransparent() || hasOverflowClip();
    533532}
    534533
  • trunk/WebCore/rendering/render_object.h

    r13346 r13366  
    748748    virtual void position(InlineBox*, int, int, bool, bool) {}
    749749
     750    bool isTransparent() const { return style()->opacity() < 1.0f; }
     751    float opacity() const { return style()->opacity(); }
     752
    750753    // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks.
    751754    int maximalOutlineSize(PaintAction p) const;
Note: See TracChangeset for help on using the changeset viewer.