Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 1997 Martin Jones (mjones (at) kde.org)
      3  *           (C) 1997 Torben Weis (weis (at) kde.org)
      4  *           (C) 1998 Waldo Bastian (bastian (at) kde.org)
      5  *           (C) 1999 Lars Knoll (knoll (at) kde.org)
      6  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      7  * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010 Apple Inc. All rights reserved.
      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 #ifndef RenderTable_h
     26 #define RenderTable_h
     27 
     28 #include "CSSPropertyNames.h"
     29 #include "RenderBlock.h"
     30 #include <wtf/Vector.h>
     31 
     32 namespace WebCore {
     33 
     34 class CollapsedBorderValue;
     35 class RenderTableCol;
     36 class RenderTableCell;
     37 class RenderTableSection;
     38 class TableLayout;
     39 
     40 class RenderTable : public RenderBlock {
     41 public:
     42     explicit RenderTable(Node*);
     43     virtual ~RenderTable();
     44 
     45     int getColumnPos(int col) const { return m_columnPos[col]; }
     46 
     47     int hBorderSpacing() const { return m_hSpacing; }
     48     int vBorderSpacing() const { return m_vSpacing; }
     49 
     50     bool collapseBorders() const { return style()->borderCollapse(); }
     51 
     52     int borderStart() const { return m_borderStart; }
     53     int borderEnd() const { return m_borderEnd; }
     54     int borderBefore() const;
     55     int borderAfter() const;
     56 
     57     int borderLeft() const
     58     {
     59         if (style()->isHorizontalWritingMode())
     60             return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
     61         return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
     62     }
     63 
     64     int borderRight() const
     65     {
     66         if (style()->isHorizontalWritingMode())
     67             return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
     68         return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
     69     }
     70 
     71     int borderTop() const
     72     {
     73         if (style()->isHorizontalWritingMode())
     74             return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
     75         return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
     76     }
     77 
     78     int borderBottom() const
     79     {
     80         if (style()->isHorizontalWritingMode())
     81             return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
     82         return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
     83     }
     84 
     85     const Color bgColor() const { return style()->visitedDependentColor(CSSPropertyBackgroundColor); }
     86 
     87     int outerBorderBefore() const;
     88     int outerBorderAfter() const;
     89     int outerBorderStart() const;
     90     int outerBorderEnd() const;
     91 
     92     int outerBorderLeft() const
     93     {
     94         if (style()->isHorizontalWritingMode())
     95             return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
     96         return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
     97     }
     98 
     99     int outerBorderRight() const
    100     {
    101         if (style()->isHorizontalWritingMode())
    102             return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
    103         return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
    104     }
    105 
    106     int outerBorderTop() const
    107     {
    108         if (style()->isHorizontalWritingMode())
    109             return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
    110         return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
    111     }
    112 
    113     int outerBorderBottom() const
    114     {
    115         if (style()->isHorizontalWritingMode())
    116             return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
    117         return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
    118     }
    119 
    120     int calcBorderStart() const;
    121     int calcBorderEnd() const;
    122     void recalcBordersInRowDirection();
    123 
    124     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
    125 
    126     struct ColumnStruct {
    127         enum {
    128             WidthUndefined = 0xffff
    129         };
    130 
    131         ColumnStruct()
    132             : span(1)
    133             , width(WidthUndefined)
    134         {
    135         }
    136 
    137         unsigned span;
    138         unsigned width; // the calculated position of the column
    139     };
    140 
    141     Vector<ColumnStruct>& columns() { return m_columns; }
    142     Vector<int>& columnPositions() { return m_columnPos; }
    143     RenderTableSection* header() const { return m_head; }
    144     RenderTableSection* footer() const { return m_foot; }
    145     RenderTableSection* firstBody() const { return m_firstBody; }
    146 
    147     void splitColumn(int pos, int firstSpan);
    148     void appendColumn(int span);
    149     int numEffCols() const { return m_columns.size(); }
    150     int spanOfEffCol(int effCol) const { return m_columns[effCol].span; }
    151 
    152     int colToEffCol(int col) const
    153     {
    154         int i = 0;
    155         int effCol = numEffCols();
    156         for (int c = 0; c < col && i < effCol; ++i)
    157             c += m_columns[i].span;
    158         return i;
    159     }
    160 
    161     int effColToCol(int effCol) const
    162     {
    163         int c = 0;
    164         for (int i = 0; i < effCol; i++)
    165             c += m_columns[i].span;
    166         return c;
    167     }
    168 
    169     int bordersPaddingAndSpacingInRowDirection() const
    170     {
    171         return borderStart() + borderEnd() +
    172                (collapseBorders() ? 0 : (paddingStart() + paddingEnd() + (numEffCols() + 1) * hBorderSpacing()));
    173     }
    174 
    175     RenderTableCol* colElement(int col, bool* startEdge = 0, bool* endEdge = 0) const;
    176     RenderTableCol* nextColElement(RenderTableCol* current) const;
    177 
    178     bool needsSectionRecalc() const { return m_needsSectionRecalc; }
    179     void setNeedsSectionRecalc()
    180     {
    181         if (documentBeingDestroyed())
    182             return;
    183         m_needsSectionRecalc = true;
    184         setNeedsLayout(true);
    185     }
    186 
    187     RenderTableSection* sectionAbove(const RenderTableSection*, bool skipEmptySections = false) const;
    188     RenderTableSection* sectionBelow(const RenderTableSection*, bool skipEmptySections = false) const;
    189 
    190     RenderTableCell* cellAbove(const RenderTableCell*) const;
    191     RenderTableCell* cellBelow(const RenderTableCell*) const;
    192     RenderTableCell* cellBefore(const RenderTableCell*) const;
    193     RenderTableCell* cellAfter(const RenderTableCell*) const;
    194 
    195     const CollapsedBorderValue* currentBorderStyle() const { return m_currentBorder; }
    196 
    197     bool hasSections() const { return m_head || m_foot || m_firstBody; }
    198 
    199     void recalcSectionsIfNeeded() const
    200     {
    201         if (m_needsSectionRecalc)
    202             recalcSections();
    203     }
    204 
    205 #ifdef ANDROID_LAYOUT
    206     void clearSingleColumn() { m_singleColumn = false; }
    207     bool isSingleColumn() const { return m_singleColumn; }
    208 #endif
    209 
    210 protected:
    211     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    212 
    213 private:
    214     virtual const char* renderName() const { return "RenderTable"; }
    215 
    216     virtual bool isTable() const { return true; }
    217 
    218     virtual bool avoidsFloats() const { return true; }
    219 
    220     virtual void removeChild(RenderObject* oldChild);
    221 
    222     virtual void paint(PaintInfo&, int tx, int ty);
    223     virtual void paintObject(PaintInfo&, int tx, int ty);
    224     virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
    225     virtual void paintMask(PaintInfo&, int tx, int ty);
    226     virtual void layout();
    227     virtual void computePreferredLogicalWidths();
    228     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int xPos, int yPos, int tx, int ty, HitTestAction);
    229 
    230     virtual int firstLineBoxBaseline() const;
    231 
    232     virtual RenderBlock* firstLineBlock() const;
    233     virtual void updateFirstLetter();
    234 
    235     virtual void setCellLogicalWidths();
    236 
    237     virtual void computeLogicalWidth();
    238 
    239     virtual IntRect overflowClipRect(int tx, int ty, OverlayScrollbarSizeRelevancy relevancy = IgnoreOverlayScrollbarSize);
    240 
    241     virtual void addOverflowFromChildren();
    242 
    243     void subtractCaptionRect(IntRect&) const;
    244 
    245     void recalcCaption(RenderBlock*) const;
    246     void recalcSections() const;
    247     void adjustLogicalHeightForCaption();
    248 
    249     mutable Vector<int> m_columnPos;
    250     mutable Vector<ColumnStruct> m_columns;
    251 
    252     mutable RenderBlock* m_caption;
    253     mutable RenderTableSection* m_head;
    254     mutable RenderTableSection* m_foot;
    255     mutable RenderTableSection* m_firstBody;
    256 
    257     OwnPtr<TableLayout> m_tableLayout;
    258 
    259     const CollapsedBorderValue* m_currentBorder;
    260 
    261     mutable bool m_hasColElements : 1;
    262     mutable bool m_needsSectionRecalc : 1;
    263 
    264 #ifdef ANDROID_LAYOUT
    265     bool m_singleColumn;        // BS(Grace): should I use compact version?
    266 #endif
    267     short m_hSpacing;
    268     short m_vSpacing;
    269     int m_borderStart;
    270     int m_borderEnd;
    271 };
    272 
    273 inline RenderTable* toRenderTable(RenderObject* object)
    274 {
    275     ASSERT(!object || object->isTable());
    276     return static_cast<RenderTable*>(object);
    277 }
    278 
    279 inline const RenderTable* toRenderTable(const RenderObject* object)
    280 {
    281     ASSERT(!object || object->isTable());
    282     return static_cast<const RenderTable*>(object);
    283 }
    284 
    285 // This will catch anyone doing an unnecessary cast.
    286 void toRenderTable(const RenderTable*);
    287 
    288 } // namespace WebCore
    289 
    290 #endif // RenderTable_h
    291