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