WebCore/rendering/RenderTableRow.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /**
       
     2  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
       
     3  *           (C) 1997 Torben Weis (weis@kde.org)
       
     4  *           (C) 1998 Waldo Bastian (bastian@kde.org)
       
     5  *           (C) 1999 Lars Knoll (knoll@kde.org)
       
     6  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
       
     7  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
       
     8  *
       
     9  * This library is free software; you can redistribute it and/or
       
    10  * modify it under the terms of the GNU Library General Public
       
    11  * License as published by the Free Software Foundation; either
       
    12  * version 2 of the License, or (at your option) any later version.
       
    13  *
       
    14  * This library is distributed in the hope that it will be useful,
       
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    17  * Library General Public License for more details.
       
    18  *
       
    19  * You should have received a copy of the GNU Library General Public License
       
    20  * along with this library; see the file COPYING.LIB.  If not, write to
       
    21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    22  * Boston, MA 02110-1301, USA.
       
    23  */
       
    24 
       
    25 #include "config.h"
       
    26 #include "RenderTableRow.h"
       
    27 
       
    28 #include "CachedImage.h"
       
    29 #include "Document.h"
       
    30 #include "HTMLNames.h"
       
    31 #include "RenderTableCell.h"
       
    32 #include "RenderView.h"
       
    33 
       
    34 namespace WebCore {
       
    35 
       
    36 using namespace HTMLNames;
       
    37 
       
    38 RenderTableRow::RenderTableRow(Node* node)
       
    39     : RenderBox(node)
       
    40 {
       
    41     // init RenderObject attributes
       
    42     setInline(false);   // our object is not Inline
       
    43 }
       
    44 
       
    45 void RenderTableRow::destroy()
       
    46 {
       
    47     RenderTableSection* recalcSection = section();
       
    48     
       
    49     RenderBox::destroy();
       
    50     
       
    51     if (recalcSection)
       
    52         recalcSection->setNeedsCellRecalc();
       
    53 }
       
    54 
       
    55 void RenderTableRow::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
       
    56 {
       
    57     if (section() && style() && style()->height() != newStyle->height())
       
    58         section()->setNeedsCellRecalc();
       
    59 
       
    60     ASSERT(newStyle->display() == TABLE_ROW);
       
    61 
       
    62     RenderBox::styleWillChange(diff, newStyle);
       
    63 }
       
    64 
       
    65 void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
       
    66 {
       
    67     // Make sure we don't append things after :after-generated content if we have it.
       
    68     if (!beforeChild && isAfterContent(lastChild()))
       
    69         beforeChild = lastChild();
       
    70 
       
    71     if (!child->isTableCell()) {
       
    72         RenderObject* last = beforeChild;
       
    73         if (!last)
       
    74             last = lastChild();
       
    75         if (last && last->isAnonymous() && last->isTableCell()) {
       
    76             last->addChild(child);
       
    77             return;
       
    78         }
       
    79 
       
    80         // If beforeChild is inside an anonymous cell, insert into the cell.
       
    81         if (last && !last->isTableCell() && last->parent() && last->parent()->isAnonymous()) {
       
    82             last->parent()->addChild(child, beforeChild);
       
    83             return;
       
    84         }
       
    85 
       
    86         RenderTableCell* cell = new (renderArena()) RenderTableCell(document() /* anonymous object */);
       
    87         RefPtr<RenderStyle> newStyle = RenderStyle::create();
       
    88         newStyle->inheritFrom(style());
       
    89         newStyle->setDisplay(TABLE_CELL);
       
    90         cell->setStyle(newStyle.release());
       
    91         addChild(cell, beforeChild);
       
    92         cell->addChild(child);
       
    93         return;
       
    94     } 
       
    95     
       
    96     // If the next renderer is actually wrapped in an anonymous table cell, we need to go up and find that.
       
    97     while (beforeChild && beforeChild->parent() != this)
       
    98         beforeChild = beforeChild->parent();
       
    99 
       
   100     RenderTableCell* cell = toRenderTableCell(child);
       
   101 
       
   102     // Generated content can result in us having a null section so make sure to null check our parent.
       
   103     if (parent())
       
   104         section()->addCell(cell, this);
       
   105 
       
   106     ASSERT(!beforeChild || beforeChild->isTableCell());
       
   107     RenderBox::addChild(cell, beforeChild);
       
   108 
       
   109     if (beforeChild || nextSibling())
       
   110         section()->setNeedsCellRecalc();
       
   111 }
       
   112 
       
   113 void RenderTableRow::layout()
       
   114 {
       
   115     ASSERT(needsLayout());
       
   116 
       
   117     // Table rows do not add translation.
       
   118     LayoutStateMaintainer statePusher(view(), this, IntSize());
       
   119 
       
   120     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
       
   121         if (child->isTableCell()) {
       
   122             RenderTableCell* cell = toRenderTableCell(child);
       
   123             if (child->needsLayout()) {
       
   124                 cell->calcVerticalMargins();
       
   125                 cell->layout();
       
   126             }
       
   127         }
       
   128     }
       
   129 
       
   130     // We only ever need to repaint if our cells didn't, which menas that they didn't need
       
   131     // layout, so we know that our bounds didn't change. This code is just making up for
       
   132     // the fact that we did not repaint in setStyle() because we had a layout hint.
       
   133     // We cannot call repaint() because our clippedOverflowRectForRepaint() is taken from the
       
   134     // parent table, and being mid-layout, that is invalid. Instead, we repaint our cells.
       
   135     if (selfNeedsLayout() && checkForRepaintDuringLayout()) {
       
   136         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
       
   137             if (child->isTableCell())
       
   138                 child->repaint();
       
   139         }
       
   140     }
       
   141 
       
   142     statePusher.pop();
       
   143     setNeedsLayout(false);
       
   144 }
       
   145 
       
   146 IntRect RenderTableRow::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
       
   147 {
       
   148     ASSERT(parent());
       
   149 
       
   150     if (repaintContainer == this)
       
   151         return RenderBox::clippedOverflowRectForRepaint(repaintContainer);
       
   152 
       
   153     // For now, just repaint the whole table.
       
   154     // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we
       
   155     // might have propagated a background color into.
       
   156     // FIXME: do repaintContainer checks here
       
   157     if (RenderTable* parentTable = table())
       
   158         return parentTable->clippedOverflowRectForRepaint(repaintContainer);
       
   159 
       
   160     return IntRect();
       
   161 }
       
   162 
       
   163 // Hit Testing
       
   164 bool RenderTableRow::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction action)
       
   165 {
       
   166     // Table rows cannot ever be hit tested.  Effectively they do not exist.
       
   167     // Just forward to our children always.
       
   168     for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
       
   169         // FIXME: We have to skip over inline flows, since they can show up inside table rows
       
   170         // at the moment (a demoted inline <form> for example). If we ever implement a
       
   171         // table-specific hit-test method (which we should do for performance reasons anyway),
       
   172         // then we can remove this check.
       
   173         if (child->isTableCell() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, x, y, tx, ty, action)) {
       
   174             updateHitTestResult(result, IntPoint(x - tx, y - ty));
       
   175             return true;
       
   176         }
       
   177     }
       
   178     
       
   179     return false;
       
   180 }
       
   181 
       
   182 void RenderTableRow::paint(PaintInfo& paintInfo, int tx, int ty)
       
   183 {
       
   184     ASSERT(hasSelfPaintingLayer());
       
   185     if (!layer())
       
   186         return;
       
   187     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
       
   188         if (child->isTableCell()) {
       
   189             // Paint the row background behind the cell.
       
   190             if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground) {
       
   191                 RenderTableCell* cell = toRenderTableCell(child);
       
   192                 cell->paintBackgroundsBehindCell(paintInfo, tx, ty, this);
       
   193             }
       
   194             if (!toRenderBox(child)->hasSelfPaintingLayer())
       
   195                 child->paint(paintInfo, tx, ty);
       
   196         }
       
   197     }
       
   198 }
       
   199 
       
   200 void RenderTableRow::imageChanged(WrappedImagePtr, const IntRect*)
       
   201 {
       
   202     // FIXME: Examine cells and repaint only the rect the image paints in.
       
   203     repaint();
       
   204 }
       
   205 
       
   206 } // namespace WebCore