Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / RenderTable.cpp
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, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
8  * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25
26 #include "config.h"
27 #include "core/rendering/RenderTable.h"
28
29 #include "core/HTMLNames.h"
30 #include "core/dom/Document.h"
31 #include "core/frame/FrameView.h"
32 #include "core/html/HTMLTableElement.h"
33 #include "core/rendering/AutoTableLayout.h"
34 #include "core/rendering/FixedTableLayout.h"
35 #include "core/rendering/GraphicsContextAnnotator.h"
36 #include "core/rendering/HitTestResult.h"
37 #include "core/rendering/RenderLayer.h"
38 #include "core/rendering/RenderTableCaption.h"
39 #include "core/rendering/RenderTableCell.h"
40 #include "core/rendering/RenderTableCol.h"
41 #include "core/rendering/RenderTableSection.h"
42 #include "core/rendering/RenderView.h"
43 #include "core/rendering/SubtreeLayoutScope.h"
44 #include "core/rendering/TextAutosizer.h"
45 #include "core/rendering/style/StyleInheritedData.h"
46 #include "platform/graphics/GraphicsContextStateSaver.h"
47
48 namespace blink {
49
50 using namespace HTMLNames;
51
52 RenderTable::RenderTable(Element* element)
53     : RenderBlock(element)
54     , m_head(0)
55     , m_foot(0)
56     , m_firstBody(0)
57     , m_currentBorder(0)
58     , m_collapsedBordersValid(false)
59     , m_hasColElements(false)
60     , m_needsSectionRecalc(false)
61     , m_columnLogicalWidthChanged(false)
62     , m_columnRenderersValid(false)
63     , m_hasCellColspanThatDeterminesTableWidth(false)
64     , m_hSpacing(0)
65     , m_vSpacing(0)
66     , m_borderStart(0)
67     , m_borderEnd(0)
68 {
69     ASSERT(!childrenInline());
70     m_columnPos.fill(0, 1);
71 }
72
73 RenderTable::~RenderTable()
74 {
75 }
76
77 void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
78 {
79     RenderBlock::styleDidChange(diff, oldStyle);
80     propagateStyleToAnonymousChildren();
81
82     bool oldFixedTableLayout = oldStyle ? oldStyle->isFixedTableLayout() : false;
83
84     // In the collapsed border model, there is no cell spacing.
85     m_hSpacing = collapseBorders() ? 0 : style()->horizontalBorderSpacing();
86     m_vSpacing = collapseBorders() ? 0 : style()->verticalBorderSpacing();
87     m_columnPos[0] = m_hSpacing;
88
89     if (!m_tableLayout || style()->isFixedTableLayout() != oldFixedTableLayout) {
90         if (m_tableLayout)
91             m_tableLayout->willChangeTableLayout();
92
93         // According to the CSS2 spec, you only use fixed table layout if an
94         // explicit width is specified on the table.  Auto width implies auto table layout.
95         if (style()->isFixedTableLayout())
96             m_tableLayout = adoptPtr(new FixedTableLayout(this));
97         else
98             m_tableLayout = adoptPtr(new AutoTableLayout(this));
99     }
100
101     // If border was changed, invalidate collapsed borders cache.
102     if (!needsLayout() && oldStyle && oldStyle->border() != style()->border())
103         invalidateCollapsedBorders();
104 }
105
106 static inline void resetSectionPointerIfNotBefore(RenderTableSection*& ptr, RenderObject* before)
107 {
108     if (!before || !ptr)
109         return;
110     RenderObject* o = before->previousSibling();
111     while (o && o != ptr)
112         o = o->previousSibling();
113     if (!o)
114         ptr = 0;
115 }
116
117 static inline bool needsTableSection(RenderObject* object)
118 {
119     // Return true if 'object' can't exist in an anonymous table without being
120     // wrapped in a table section box.
121     EDisplay display = object->style()->display();
122     return display != TABLE_CAPTION && display != TABLE_COLUMN_GROUP && display != TABLE_COLUMN;
123 }
124
125 void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
126 {
127     bool wrapInAnonymousSection = !child->isOutOfFlowPositioned();
128
129     if (child->isTableCaption())
130         wrapInAnonymousSection = false;
131     else if (child->isRenderTableCol()) {
132         m_hasColElements = true;
133         wrapInAnonymousSection = false;
134     } else if (child->isTableSection()) {
135         switch (child->style()->display()) {
136             case TABLE_HEADER_GROUP:
137                 resetSectionPointerIfNotBefore(m_head, beforeChild);
138                 if (!m_head) {
139                     m_head = toRenderTableSection(child);
140                 } else {
141                     resetSectionPointerIfNotBefore(m_firstBody, beforeChild);
142                     if (!m_firstBody)
143                         m_firstBody = toRenderTableSection(child);
144                 }
145                 wrapInAnonymousSection = false;
146                 break;
147             case TABLE_FOOTER_GROUP:
148                 resetSectionPointerIfNotBefore(m_foot, beforeChild);
149                 if (!m_foot) {
150                     m_foot = toRenderTableSection(child);
151                     wrapInAnonymousSection = false;
152                     break;
153                 }
154                 // Fall through.
155             case TABLE_ROW_GROUP:
156                 resetSectionPointerIfNotBefore(m_firstBody, beforeChild);
157                 if (!m_firstBody)
158                     m_firstBody = toRenderTableSection(child);
159                 wrapInAnonymousSection = false;
160                 break;
161             default:
162                 ASSERT_NOT_REACHED();
163         }
164     } else
165         wrapInAnonymousSection = true;
166
167     if (child->isTableSection())
168         setNeedsSectionRecalc();
169
170     if (!wrapInAnonymousSection) {
171         if (beforeChild && beforeChild->parent() != this)
172             beforeChild = splitAnonymousBoxesAroundChild(beforeChild);
173
174         RenderBox::addChild(child, beforeChild);
175         return;
176     }
177
178     if (!beforeChild && lastChild() && lastChild()->isTableSection() && lastChild()->isAnonymous() && !lastChild()->isBeforeContent()) {
179         lastChild()->addChild(child);
180         return;
181     }
182
183     if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
184         RenderObject* section = beforeChild->previousSibling();
185         if (section && section->isTableSection() && section->isAnonymous()) {
186             section->addChild(child);
187             return;
188         }
189     }
190
191     RenderObject* lastBox = beforeChild;
192     while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableSection() && needsTableSection(lastBox))
193         lastBox = lastBox->parent();
194     if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox)) {
195         if (beforeChild == lastBox)
196             beforeChild = lastBox->slowFirstChild();
197         lastBox->addChild(child, beforeChild);
198         return;
199     }
200
201     if (beforeChild && !beforeChild->isTableSection() && needsTableSection(beforeChild))
202         beforeChild = 0;
203
204     RenderTableSection* section = RenderTableSection::createAnonymousWithParentRenderer(this);
205     addChild(section, beforeChild);
206     section->addChild(child);
207 }
208
209 void RenderTable::addCaption(const RenderTableCaption* caption)
210 {
211     ASSERT(m_captions.find(caption) == kNotFound);
212     m_captions.append(const_cast<RenderTableCaption*>(caption));
213 }
214
215 void RenderTable::removeCaption(const RenderTableCaption* oldCaption)
216 {
217     size_t index = m_captions.find(oldCaption);
218     ASSERT(index != kNotFound);
219     if (index == kNotFound)
220         return;
221
222     m_captions.remove(index);
223 }
224
225 void RenderTable::invalidateCachedColumns()
226 {
227     m_columnRenderersValid = false;
228     m_columnRenderers.resize(0);
229 }
230
231 void RenderTable::addColumn(const RenderTableCol*)
232 {
233     invalidateCachedColumns();
234 }
235
236 void RenderTable::removeColumn(const RenderTableCol*)
237 {
238     invalidateCachedColumns();
239     // We don't really need to recompute our sections, but we need to update our
240     // column count and whether we have a column. Currently, we only have one
241     // size-fit-all flag but we may have to consider splitting it.
242     setNeedsSectionRecalc();
243 }
244
245 void RenderTable::updateLogicalWidth()
246 {
247     recalcSectionsIfNeeded();
248
249     if (isOutOfFlowPositioned()) {
250         LogicalExtentComputedValues computedValues;
251         computePositionedLogicalWidth(computedValues);
252         setLogicalWidth(computedValues.m_extent);
253         setLogicalLeft(computedValues.m_position);
254         setMarginStart(computedValues.m_margins.m_start);
255         setMarginEnd(computedValues.m_margins.m_end);
256     }
257
258     RenderBlock* cb = containingBlock();
259
260     LayoutUnit availableLogicalWidth = containingBlockLogicalWidthForContent() + (isOutOfFlowPositioned() ? cb->paddingLogicalWidth() : LayoutUnit(0));
261     bool hasPerpendicularContainingBlock = cb->style()->isHorizontalWritingMode() != style()->isHorizontalWritingMode();
262     LayoutUnit containerWidthInInlineDirection = hasPerpendicularContainingBlock ? perpendicularContainingBlockLogicalHeight() : availableLogicalWidth;
263
264     Length styleLogicalWidth = style()->logicalWidth();
265     if ((styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive()) || styleLogicalWidth.isIntrinsic())
266         setLogicalWidth(convertStyleLogicalWidthToComputedWidth(styleLogicalWidth, containerWidthInInlineDirection));
267     else {
268         // Subtract out any fixed margins from our available width for auto width tables.
269         LayoutUnit marginStart = minimumValueForLength(style()->marginStart(), availableLogicalWidth);
270         LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd(), availableLogicalWidth);
271         LayoutUnit marginTotal = marginStart + marginEnd;
272
273         // Subtract out our margins to get the available content width.
274         LayoutUnit availableContentLogicalWidth = std::max<LayoutUnit>(0, containerWidthInInlineDirection - marginTotal);
275         if (shrinkToAvoidFloats() && cb->isRenderBlockFlow() && toRenderBlockFlow(cb)->containsFloats() && !hasPerpendicularContainingBlock)
276             availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, toRenderBlockFlow(cb));
277
278         // Ensure we aren't bigger than our available width.
279         setLogicalWidth(std::min<int>(availableContentLogicalWidth, maxPreferredLogicalWidth()));
280     }
281
282     // Ensure we aren't bigger than our max-width style.
283     Length styleMaxLogicalWidth = style()->logicalMaxWidth();
284     if ((styleMaxLogicalWidth.isSpecified() && !styleMaxLogicalWidth.isNegative()) || styleMaxLogicalWidth.isIntrinsic()) {
285         LayoutUnit computedMaxLogicalWidth = convertStyleLogicalWidthToComputedWidth(styleMaxLogicalWidth, availableLogicalWidth);
286         setLogicalWidth(std::min<int>(logicalWidth(), computedMaxLogicalWidth));
287     }
288
289     // Ensure we aren't smaller than our min preferred width. This MUST be done after 'max-width' as
290     // we ignore it if it means we wouldn't accomodate our content.
291     setLogicalWidth(std::max<int>(logicalWidth(), minPreferredLogicalWidth()));
292
293      // Ensure we aren't smaller than our min-width style.
294     Length styleMinLogicalWidth = style()->logicalMinWidth();
295     if ((styleMinLogicalWidth.isSpecified() && !styleMinLogicalWidth.isNegative()) || styleMinLogicalWidth.isIntrinsic()) {
296         LayoutUnit computedMinLogicalWidth = convertStyleLogicalWidthToComputedWidth(styleMinLogicalWidth, availableLogicalWidth);
297         setLogicalWidth(std::max<int>(logicalWidth(), computedMinLogicalWidth));
298     }
299
300     // Finally, with our true width determined, compute our margins for real.
301     ComputedMarginValues marginValues;
302     computeMarginsForDirection(InlineDirection, cb, availableLogicalWidth, logicalWidth(), marginValues.m_start, marginValues.m_end, style()->marginStart(), style()->marginEnd());
303     setMarginStart(marginValues.m_start);
304     setMarginEnd(marginValues.m_end);
305
306     // We should NEVER shrink the table below the min-content logical width, or else the table can't accomodate
307     // its own content which doesn't match CSS nor what authors expect.
308     // FIXME: When we convert to sub-pixel layout for tables we can remove the int conversion
309     // https://code.google.com/p/chromium/issues/detail?id=241198
310     ASSERT(logicalWidth().toInt() >= minPreferredLogicalWidth().toInt());
311 }
312
313 // This method takes a RenderStyle's logical width, min-width, or max-width length and computes its actual value.
314 LayoutUnit RenderTable::convertStyleLogicalWidthToComputedWidth(const Length& styleLogicalWidth, LayoutUnit availableWidth)
315 {
316     if (styleLogicalWidth.isIntrinsic())
317         return computeIntrinsicLogicalWidthUsing(styleLogicalWidth, availableWidth, bordersPaddingAndSpacingInRowDirection());
318
319     // HTML tables' width styles already include borders and paddings, but CSS tables' width styles do not.
320     LayoutUnit borders = 0;
321     bool isCSSTable = !isHTMLTableElement(node());
322     if (isCSSTable && styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive() && style()->boxSizing() == CONTENT_BOX)
323         borders = borderStart() + borderEnd() + (collapseBorders() ? LayoutUnit() : paddingStart() + paddingEnd());
324
325     return minimumValueForLength(styleLogicalWidth, availableWidth) + borders;
326 }
327
328 LayoutUnit RenderTable::convertStyleLogicalHeightToComputedHeight(const Length& styleLogicalHeight)
329 {
330     LayoutUnit borderAndPaddingBefore = borderBefore() + (collapseBorders() ? LayoutUnit() : paddingBefore());
331     LayoutUnit borderAndPaddingAfter = borderAfter() + (collapseBorders() ? LayoutUnit() : paddingAfter());
332     LayoutUnit borderAndPadding = borderAndPaddingBefore + borderAndPaddingAfter;
333     LayoutUnit computedLogicalHeight = 0;
334     if (styleLogicalHeight.isFixed()) {
335         // HTML tables size as though CSS height includes border/padding, CSS tables do not.
336         LayoutUnit borders = LayoutUnit();
337         // FIXME: We cannot apply box-sizing: content-box on <table> which other browsers allow.
338         if (isHTMLTableElement(node()) || style()->boxSizing() == BORDER_BOX) {
339             borders = borderAndPadding;
340         }
341         computedLogicalHeight = styleLogicalHeight.value() - borders;
342     } else if (styleLogicalHeight.isPercent())
343         computedLogicalHeight = computePercentageLogicalHeight(styleLogicalHeight);
344     else if (styleLogicalHeight.isIntrinsic())
345         computedLogicalHeight = computeIntrinsicLogicalContentHeightUsing(styleLogicalHeight, logicalHeight() - borderAndPadding, borderAndPadding);
346     else
347         ASSERT_NOT_REACHED();
348     return std::max<LayoutUnit>(0, computedLogicalHeight);
349 }
350
351 void RenderTable::layoutCaption(RenderTableCaption* caption)
352 {
353     if (caption->needsLayout()) {
354         // The margins may not be available but ensure the caption is at least located beneath any previous sibling caption
355         // so that it does not mistakenly think any floats in the previous caption intrude into it.
356         caption->setLogicalLocation(LayoutPoint(caption->marginStart(), collapsedMarginBeforeForChild(caption) + logicalHeight()));
357         // If RenderTableCaption ever gets a layout() function, use it here.
358         caption->layoutIfNeeded();
359     }
360     // Apply the margins to the location now that they are definitely available from layout
361     LayoutUnit captionLogicalTop = collapsedMarginBeforeForChild(caption) + logicalHeight();
362     if (view()->layoutState()->isPaginated()) {
363         captionLogicalTop += caption->paginationStrut();
364         caption->setPaginationStrut(0);
365     }
366     caption->setLogicalLocation(LayoutPoint(caption->marginStart(), captionLogicalTop));
367
368     if (!selfNeedsLayout())
369         caption->setMayNeedPaintInvalidation(true);
370
371     setLogicalHeight(logicalHeight() + caption->logicalHeight() + collapsedMarginBeforeForChild(caption) + collapsedMarginAfterForChild(caption));
372 }
373
374 void RenderTable::distributeExtraLogicalHeight(int extraLogicalHeight)
375 {
376     if (extraLogicalHeight <= 0)
377         return;
378
379     // FIXME: Distribute the extra logical height between all table sections instead of giving it all to the first one.
380     if (RenderTableSection* section = firstBody())
381         extraLogicalHeight -= section->distributeExtraLogicalHeightToRows(extraLogicalHeight);
382
383     // FIXME: We really would like to enable this ASSERT to ensure that all the extra space has been distributed.
384     // However our current distribution algorithm does not round properly and thus we can have some remaining height.
385     // ASSERT(!topSection() || !extraLogicalHeight);
386 }
387
388 void RenderTable::simplifiedNormalFlowLayout()
389 {
390     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) {
391         section->layoutIfNeeded();
392         section->computeOverflowFromCells();
393     }
394 }
395
396 void RenderTable::layout()
397 {
398     ASSERT(needsLayout());
399
400     if (simplifiedLayout())
401         return;
402
403     // Note: RenderTable is handled differently than other RenderBlocks and the LayoutScope
404     //       must be created before the table begins laying out.
405     TextAutosizer::LayoutScope textAutosizerLayoutScope(this);
406
407     recalcSectionsIfNeeded();
408     // FIXME: We should do this recalc lazily in borderStart/borderEnd so that we don't have to make sure
409     // to call this before we call borderStart/borderEnd to avoid getting a stale value.
410     recalcBordersInRowDirection();
411
412     SubtreeLayoutScope layouter(*this);
413
414     // If any table section moved vertically, we will just repaint everything from that
415     // section down (it is quite unlikely that any of the following sections
416     // did not shift).
417     bool sectionMoved = false;
418     LayoutUnit movedSectionLogicalTop = 0;
419     {
420         LayoutState state(*this, locationOffset());
421
422         setLogicalHeight(0);
423
424         LayoutUnit oldLogicalWidth = logicalWidth();
425         updateLogicalWidth();
426
427         if (logicalWidth() != oldLogicalWidth) {
428             for (unsigned i = 0; i < m_captions.size(); i++)
429                 layouter.setNeedsLayout(m_captions[i]);
430         }
431         // FIXME: The optimisation below doesn't work since the internal table
432         // layout could have changed. We need to add a flag to the table
433         // layout that tells us if something has changed in the min max
434         // calculations to do it correctly.
435         // if ( oldWidth != width() || columns.size() + 1 != columnPos.size() )
436         m_tableLayout->layout();
437
438         LayoutUnit totalSectionLogicalHeight = 0;
439         LayoutUnit oldTableLogicalTop = 0;
440         for (unsigned i = 0; i < m_captions.size(); i++)
441             oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
442
443         bool collapsing = collapseBorders();
444
445         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
446             if (child->isTableSection()) {
447                 RenderTableSection* section = toRenderTableSection(child);
448                 if (m_columnLogicalWidthChanged)
449                     layouter.setChildNeedsLayout(section);
450                 section->layoutIfNeeded();
451                 totalSectionLogicalHeight += section->calcRowLogicalHeight();
452                 if (collapsing)
453                     section->recalcOuterBorder();
454                 ASSERT(!section->needsLayout());
455             } else if (child->isRenderTableCol()) {
456                 child->layoutIfNeeded();
457                 ASSERT(!child->needsLayout());
458             } else {
459                 // FIXME: We should never have other type of children (they should be wrapped in an
460                 // anonymous table section) but our code is too crazy and this can happen in practice.
461                 // Until this is fixed, let's make sure we don't leave non laid out children in the tree.
462                 child->layoutIfNeeded();
463             }
464         }
465
466         // FIXME: Collapse caption margin.
467         if (!m_captions.isEmpty()) {
468             for (unsigned i = 0; i < m_captions.size(); i++) {
469                 if (m_captions[i]->style()->captionSide() == CAPBOTTOM)
470                     continue;
471                 layoutCaption(m_captions[i]);
472             }
473             if (logicalHeight() != oldTableLogicalTop) {
474                 sectionMoved = true;
475                 movedSectionLogicalTop = std::min(logicalHeight(), oldTableLogicalTop);
476             }
477         }
478
479         LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? LayoutUnit() : paddingBefore());
480         LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? LayoutUnit() : paddingAfter());
481
482         setLogicalHeight(logicalHeight() + borderAndPaddingBefore);
483
484         LayoutUnit computedLogicalHeight = 0;
485
486         Length logicalHeightLength = style()->logicalHeight();
487         if (logicalHeightLength.isIntrinsic() || (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive()))
488             computedLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
489
490         Length logicalMaxHeightLength = style()->logicalMaxHeight();
491         if (logicalMaxHeightLength.isIntrinsic() || (logicalMaxHeightLength.isSpecified() && !logicalMaxHeightLength.isNegative())) {
492             LayoutUnit computedMaxLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMaxHeightLength);
493             computedLogicalHeight = std::min(computedLogicalHeight, computedMaxLogicalHeight);
494         }
495
496         Length logicalMinHeightLength = style()->logicalMinHeight();
497         if (logicalMinHeightLength.isIntrinsic() || (logicalMinHeightLength.isSpecified() && !logicalMinHeightLength.isNegative())) {
498             LayoutUnit computedMinLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMinHeightLength);
499             computedLogicalHeight = std::max(computedLogicalHeight, computedMinLogicalHeight);
500         }
501
502         distributeExtraLogicalHeight(floorToInt(computedLogicalHeight - totalSectionLogicalHeight));
503
504         for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
505             section->layoutRows();
506
507         if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !document().inQuirksMode()) {
508             // Completely empty tables (with no sections or anything) should at least honor specified height
509             // in strict mode.
510             setLogicalHeight(logicalHeight() + computedLogicalHeight);
511         }
512
513         LayoutUnit sectionLogicalLeft = style()->isLeftToRightDirection() ? borderStart() : borderEnd();
514         if (!collapsing)
515             sectionLogicalLeft += style()->isLeftToRightDirection() ? paddingStart() : paddingEnd();
516
517         // position the table sections
518         RenderTableSection* section = topSection();
519         while (section) {
520             if (!sectionMoved && section->logicalTop() != logicalHeight()) {
521                 sectionMoved = true;
522                 movedSectionLogicalTop = std::min(logicalHeight(), section->logicalTop()) + (style()->isHorizontalWritingMode() ? section->visualOverflowRect().y() : section->visualOverflowRect().x());
523             }
524             section->setLogicalLocation(LayoutPoint(sectionLogicalLeft, logicalHeight()));
525
526             // As we may skip invalidation on the table, we need to ensure that sections are invalidated when they moved.
527             if (sectionMoved && !section->selfNeedsLayout())
528                 section->setMayNeedPaintInvalidation(true);
529
530             setLogicalHeight(logicalHeight() + section->logicalHeight());
531
532             section = sectionBelow(section);
533         }
534
535         setLogicalHeight(logicalHeight() + borderAndPaddingAfter);
536
537         for (unsigned i = 0; i < m_captions.size(); i++) {
538             if (m_captions[i]->style()->captionSide() != CAPBOTTOM)
539                 continue;
540             layoutCaption(m_captions[i]);
541         }
542
543         updateLogicalHeight();
544
545         // table can be containing block of positioned elements.
546         // FIXME: Only pass true if width or height changed.
547         layoutPositionedObjects(true);
548
549         updateLayerTransformAfterLayout();
550
551         // Layout was changed, so probably borders too.
552         invalidateCollapsedBorders();
553
554         computeOverflow(clientLogicalBottom());
555     }
556
557     // FIXME: This value isn't the intrinsic content logical height, but we need
558     // to update the value as its used by flexbox layout. crbug.com/367324
559     updateIntrinsicContentLogicalHeight(contentLogicalHeight());
560
561     if (view()->layoutState()->pageLogicalHeight())
562         setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(*this, logicalTop()));
563
564     m_columnLogicalWidthChanged = false;
565     clearNeedsLayout();
566 }
567
568 // Collect all the unique border values that we want to paint in a sorted list.
569 void RenderTable::recalcCollapsedBorders()
570 {
571     if (m_collapsedBordersValid)
572         return;
573     m_collapsedBordersValid = true;
574     m_collapsedBorders.clear();
575     for (RenderObject* section = firstChild(); section; section = section->nextSibling()) {
576         if (!section->isTableSection())
577             continue;
578         for (RenderTableRow* row = toRenderTableSection(section)->firstRow(); row; row = row->nextRow()) {
579             for (RenderTableCell* cell = row->firstCell(); cell; cell = cell->nextCell()) {
580                 ASSERT(cell->table() == this);
581                 cell->collectBorderValues(m_collapsedBorders);
582             }
583         }
584     }
585     RenderTableCell::sortBorderValues(m_collapsedBorders);
586 }
587
588
589 void RenderTable::addOverflowFromChildren()
590 {
591     // Add overflow from borders.
592     // Technically it's odd that we are incorporating the borders into layout overflow, which is only supposed to be about overflow from our
593     // descendant objects, but since tables don't support overflow:auto, this works out fine.
594     if (collapseBorders()) {
595         int rightBorderOverflow = width() + outerBorderRight() - borderRight();
596         int leftBorderOverflow = borderLeft() - outerBorderLeft();
597         int bottomBorderOverflow = height() + outerBorderBottom() - borderBottom();
598         int topBorderOverflow = borderTop() - outerBorderTop();
599         IntRect borderOverflowRect(leftBorderOverflow, topBorderOverflow, rightBorderOverflow - leftBorderOverflow, bottomBorderOverflow - topBorderOverflow);
600         if (borderOverflowRect != pixelSnappedBorderBoxRect()) {
601             addLayoutOverflow(borderOverflowRect);
602             addVisualOverflow(borderOverflowRect);
603         }
604     }
605
606     // Add overflow from our caption.
607     for (unsigned i = 0; i < m_captions.size(); i++)
608         addOverflowFromChild(m_captions[i]);
609
610     // Add overflow from our sections.
611     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
612         addOverflowFromChild(section);
613 }
614
615 void RenderTable::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
616 {
617     ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
618
619     LayoutPoint adjustedPaintOffset = paintOffset + location();
620
621     PaintPhase paintPhase = paintInfo.phase;
622
623     if (!isDocumentElement()) {
624         LayoutRect overflowBox = visualOverflowRect();
625         flipForWritingMode(overflowBox);
626         overflowBox.moveBy(adjustedPaintOffset);
627         if (!overflowBox.intersects(paintInfo.rect))
628             return;
629     }
630
631     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, ForceContentsClip);
632     paintObject(paintInfo, adjustedPaintOffset);
633     if (pushedClip)
634         popContentsClip(paintInfo, paintPhase, adjustedPaintOffset);
635 }
636
637 void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
638 {
639     PaintPhase paintPhase = paintInfo.phase;
640     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && hasBoxDecorationBackground() && style()->visibility() == VISIBLE)
641         paintBoxDecorationBackground(paintInfo, paintOffset);
642
643     if (paintPhase == PaintPhaseMask) {
644         paintMask(paintInfo, paintOffset);
645         return;
646     }
647
648     // We're done.  We don't bother painting any children.
649     if (paintPhase == PaintPhaseBlockBackground)
650         return;
651
652     // We don't paint our own background, but we do let the kids paint their backgrounds.
653     if (paintPhase == PaintPhaseChildBlockBackgrounds)
654         paintPhase = PaintPhaseChildBlockBackground;
655
656     PaintInfo info(paintInfo);
657     info.phase = paintPhase;
658     info.updatePaintingRootForChildren(this);
659
660     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
661         if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) {
662             LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(child), paintOffset);
663             child->paint(info, childPoint);
664         }
665     }
666
667     if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) {
668         recalcCollapsedBorders();
669         // Using our cached sorted styles, we then do individual passes,
670         // painting each style of border from lowest precedence to highest precedence.
671         info.phase = PaintPhaseCollapsedTableBorders;
672         size_t count = m_collapsedBorders.size();
673         for (size_t i = 0; i < count; ++i) {
674             m_currentBorder = &m_collapsedBorders[i];
675             for (RenderTableSection* section = bottomSection(); section; section = sectionAbove(section)) {
676                 LayoutPoint childPoint = flipForWritingModeForChild(section, paintOffset);
677                 section->paint(info, childPoint);
678             }
679         }
680         m_currentBorder = 0;
681     }
682
683     // Paint outline.
684     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
685         paintOutline(paintInfo, LayoutRect(paintOffset, size()));
686 }
687
688 void RenderTable::subtractCaptionRect(LayoutRect& rect) const
689 {
690     for (unsigned i = 0; i < m_captions.size(); i++) {
691         LayoutUnit captionLogicalHeight = m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
692         bool captionIsBefore = (m_captions[i]->style()->captionSide() != CAPBOTTOM) ^ style()->isFlippedBlocksWritingMode();
693         if (style()->isHorizontalWritingMode()) {
694             rect.setHeight(rect.height() - captionLogicalHeight);
695             if (captionIsBefore)
696                 rect.move(0, captionLogicalHeight);
697         } else {
698             rect.setWidth(rect.width() - captionLogicalHeight);
699             if (captionIsBefore)
700                 rect.move(captionLogicalHeight, 0);
701         }
702     }
703 }
704
705 void RenderTable::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
706 {
707     if (!paintInfo.shouldPaintWithinRoot(this))
708         return;
709
710     LayoutRect rect(paintOffset, size());
711     subtractCaptionRect(rect);
712     paintBoxDecorationBackgroundWithRect(paintInfo, paintOffset, rect);
713 }
714
715 void RenderTable::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
716 {
717     if (style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
718         return;
719
720     LayoutRect rect(paintOffset, size());
721     subtractCaptionRect(rect);
722
723     paintMaskImages(paintInfo, rect);
724 }
725
726 void RenderTable::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth) const
727 {
728     recalcSectionsIfNeeded();
729     // FIXME: Do the recalc in borderStart/borderEnd and make those const_cast this call.
730     // Then m_borderStart/m_borderEnd will be transparent a cache and it removes the possibility
731     // of reading out stale values.
732     const_cast<RenderTable*>(this)->recalcBordersInRowDirection();
733     // FIXME: Restructure the table layout code so that we can make this method const.
734     const_cast<RenderTable*>(this)->m_tableLayout->computeIntrinsicLogicalWidths(minWidth, maxWidth);
735
736     // FIXME: We should include captions widths here like we do in computePreferredLogicalWidths.
737 }
738
739 void RenderTable::computePreferredLogicalWidths()
740 {
741     ASSERT(preferredLogicalWidthsDirty());
742
743     computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
744
745     int bordersPaddingAndSpacing = bordersPaddingAndSpacingInRowDirection();
746     m_minPreferredLogicalWidth += bordersPaddingAndSpacing;
747     m_maxPreferredLogicalWidth += bordersPaddingAndSpacing;
748
749     m_tableLayout->applyPreferredLogicalWidthQuirks(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
750
751     for (unsigned i = 0; i < m_captions.size(); i++)
752         m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, m_captions[i]->minPreferredLogicalWidth());
753
754     RenderStyle* styleToUse = style();
755     // FIXME: This should probably be checking for isSpecified since you should be able to use percentage or calc values for min-width.
756     if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
757         m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
758         m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
759     }
760
761     // FIXME: This should probably be checking for isSpecified since you should be able to use percentage or calc values for maxWidth.
762     if (styleToUse->logicalMaxWidth().isFixed()) {
763         // We don't constrain m_minPreferredLogicalWidth as the table should be at least the size of its min-content, regardless of 'max-width'.
764         m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
765         m_maxPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
766     }
767
768     // FIXME: We should be adding borderAndPaddingLogicalWidth here, but m_tableLayout->computePreferredLogicalWidths already does,
769     // so a bunch of tests break doing this naively.
770     clearPreferredLogicalWidthsDirty();
771 }
772
773 RenderTableSection* RenderTable::topNonEmptySection() const
774 {
775     RenderTableSection* section = topSection();
776     if (section && !section->numRows())
777         section = sectionBelow(section, SkipEmptySections);
778     return section;
779 }
780
781 void RenderTable::splitColumn(unsigned position, unsigned firstSpan)
782 {
783     // We split the column at "position", taking "firstSpan" cells from the span.
784     ASSERT(m_columns[position].span > firstSpan);
785     m_columns.insert(position, ColumnStruct(firstSpan));
786     m_columns[position + 1].span -= firstSpan;
787
788     // Propagate the change in our columns representation to the sections that don't need
789     // cell recalc. If they do, they will be synced up directly with m_columns later.
790     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
791         if (!child->isTableSection())
792             continue;
793
794         RenderTableSection* section = toRenderTableSection(child);
795         if (section->needsCellRecalc())
796             continue;
797
798         section->splitColumn(position, firstSpan);
799     }
800
801     m_columnPos.grow(numEffCols() + 1);
802 }
803
804 void RenderTable::appendColumn(unsigned span)
805 {
806     unsigned newColumnIndex = m_columns.size();
807     m_columns.append(ColumnStruct(span));
808
809     // Unless the table has cell(s) with colspan that exceed the number of columns afforded
810     // by the other rows in the table we can use the fast path when mapping columns to effective columns.
811     m_hasCellColspanThatDeterminesTableWidth = m_hasCellColspanThatDeterminesTableWidth || span > 1;
812
813     // Propagate the change in our columns representation to the sections that don't need
814     // cell recalc. If they do, they will be synced up directly with m_columns later.
815     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
816         if (!child->isTableSection())
817             continue;
818
819         RenderTableSection* section = toRenderTableSection(child);
820         if (section->needsCellRecalc())
821             continue;
822
823         section->appendColumn(newColumnIndex);
824     }
825
826     m_columnPos.grow(numEffCols() + 1);
827 }
828
829 RenderTableCol* RenderTable::firstColumn() const
830 {
831     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
832         if (child->isRenderTableCol())
833             return toRenderTableCol(child);
834     }
835
836     return 0;
837 }
838
839 void RenderTable::updateColumnCache() const
840 {
841     ASSERT(m_hasColElements);
842     ASSERT(m_columnRenderers.isEmpty());
843     ASSERT(!m_columnRenderersValid);
844
845     for (RenderTableCol* columnRenderer = firstColumn(); columnRenderer; columnRenderer = columnRenderer->nextColumn()) {
846         if (columnRenderer->isTableColumnGroupWithColumnChildren())
847             continue;
848         m_columnRenderers.append(columnRenderer);
849     }
850     m_columnRenderersValid = true;
851 }
852
853 RenderTableCol* RenderTable::slowColElement(unsigned col, bool* startEdge, bool* endEdge) const
854 {
855     ASSERT(m_hasColElements);
856
857     if (!m_columnRenderersValid)
858         updateColumnCache();
859
860     unsigned columnCount = 0;
861     for (unsigned i = 0; i < m_columnRenderers.size(); i++) {
862         RenderTableCol* columnRenderer = m_columnRenderers[i];
863         unsigned span = columnRenderer->span();
864         unsigned startCol = columnCount;
865         ASSERT(span >= 1);
866         unsigned endCol = columnCount + span - 1;
867         columnCount += span;
868         if (columnCount > col) {
869             if (startEdge)
870                 *startEdge = startCol == col;
871             if (endEdge)
872                 *endEdge = endCol == col;
873             return columnRenderer;
874         }
875     }
876     return 0;
877 }
878
879 void RenderTable::recalcSections() const
880 {
881     ASSERT(m_needsSectionRecalc);
882
883     m_head = 0;
884     m_foot = 0;
885     m_firstBody = 0;
886     m_hasColElements = false;
887     m_hasCellColspanThatDeterminesTableWidth = hasCellColspanThatDeterminesTableWidth();
888
889     // We need to get valid pointers to caption, head, foot and first body again
890     RenderObject* nextSibling;
891     for (RenderObject* child = firstChild(); child; child = nextSibling) {
892         nextSibling = child->nextSibling();
893         switch (child->style()->display()) {
894         case TABLE_COLUMN:
895         case TABLE_COLUMN_GROUP:
896             m_hasColElements = true;
897             break;
898         case TABLE_HEADER_GROUP:
899             if (child->isTableSection()) {
900                 RenderTableSection* section = toRenderTableSection(child);
901                 if (!m_head)
902                     m_head = section;
903                 else if (!m_firstBody)
904                     m_firstBody = section;
905                 section->recalcCellsIfNeeded();
906             }
907             break;
908         case TABLE_FOOTER_GROUP:
909             if (child->isTableSection()) {
910                 RenderTableSection* section = toRenderTableSection(child);
911                 if (!m_foot)
912                     m_foot = section;
913                 else if (!m_firstBody)
914                     m_firstBody = section;
915                 section->recalcCellsIfNeeded();
916             }
917             break;
918         case TABLE_ROW_GROUP:
919             if (child->isTableSection()) {
920                 RenderTableSection* section = toRenderTableSection(child);
921                 if (!m_firstBody)
922                     m_firstBody = section;
923                 section->recalcCellsIfNeeded();
924             }
925             break;
926         default:
927             break;
928         }
929     }
930
931     // repair column count (addChild can grow it too much, because it always adds elements to the last row of a section)
932     unsigned maxCols = 0;
933     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
934         if (child->isTableSection()) {
935             RenderTableSection* section = toRenderTableSection(child);
936             unsigned sectionCols = section->numColumns();
937             if (sectionCols > maxCols)
938                 maxCols = sectionCols;
939         }
940     }
941
942     m_columns.resize(maxCols);
943     m_columnPos.resize(maxCols + 1);
944
945     ASSERT(selfNeedsLayout());
946
947     m_needsSectionRecalc = false;
948 }
949
950 int RenderTable::calcBorderStart() const
951 {
952     if (!collapseBorders())
953         return RenderBlock::borderStart();
954
955     // Determined by the first cell of the first row. See the CSS 2.1 spec, section 17.6.2.
956     if (!numEffCols())
957         return 0;
958
959     unsigned borderWidth = 0;
960
961     const BorderValue& tableStartBorder = style()->borderStart();
962     if (tableStartBorder.style() == BHIDDEN)
963         return 0;
964     if (tableStartBorder.style() > BHIDDEN)
965         borderWidth = tableStartBorder.width();
966
967     if (RenderTableCol* column = colElement(0)) {
968         // FIXME: We don't account for direction on columns and column groups.
969         const BorderValue& columnAdjoiningBorder = column->style()->borderStart();
970         if (columnAdjoiningBorder.style() == BHIDDEN)
971             return 0;
972         if (columnAdjoiningBorder.style() > BHIDDEN)
973             borderWidth = std::max(borderWidth, columnAdjoiningBorder.width());
974         // FIXME: This logic doesn't properly account for the first column in the first column-group case.
975     }
976
977     if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
978         const BorderValue& sectionAdjoiningBorder = topNonEmptySection->borderAdjoiningTableStart();
979         if (sectionAdjoiningBorder.style() == BHIDDEN)
980             return 0;
981
982         if (sectionAdjoiningBorder.style() > BHIDDEN)
983             borderWidth = std::max(borderWidth, sectionAdjoiningBorder.width());
984
985         if (const RenderTableCell* adjoiningStartCell = topNonEmptySection->firstRowCellAdjoiningTableStart()) {
986             // FIXME: Make this work with perpendicular and flipped cells.
987             const BorderValue& startCellAdjoiningBorder = adjoiningStartCell->borderAdjoiningTableStart();
988             if (startCellAdjoiningBorder.style() == BHIDDEN)
989                 return 0;
990
991             const BorderValue& firstRowAdjoiningBorder = adjoiningStartCell->row()->borderAdjoiningTableStart();
992             if (firstRowAdjoiningBorder.style() == BHIDDEN)
993                 return 0;
994
995             if (startCellAdjoiningBorder.style() > BHIDDEN)
996                 borderWidth = std::max(borderWidth, startCellAdjoiningBorder.width());
997             if (firstRowAdjoiningBorder.style() > BHIDDEN)
998                 borderWidth = std::max(borderWidth, firstRowAdjoiningBorder.width());
999         }
1000     }
1001     return (borderWidth + (style()->isLeftToRightDirection() ? 0 : 1)) / 2;
1002 }
1003
1004 int RenderTable::calcBorderEnd() const
1005 {
1006     if (!collapseBorders())
1007         return RenderBlock::borderEnd();
1008
1009     // Determined by the last cell of the first row. See the CSS 2.1 spec, section 17.6.2.
1010     if (!numEffCols())
1011         return 0;
1012
1013     unsigned borderWidth = 0;
1014
1015     const BorderValue& tableEndBorder = style()->borderEnd();
1016     if (tableEndBorder.style() == BHIDDEN)
1017         return 0;
1018     if (tableEndBorder.style() > BHIDDEN)
1019         borderWidth = tableEndBorder.width();
1020
1021     unsigned endColumn = numEffCols() - 1;
1022     if (RenderTableCol* column = colElement(endColumn)) {
1023         // FIXME: We don't account for direction on columns and column groups.
1024         const BorderValue& columnAdjoiningBorder = column->style()->borderEnd();
1025         if (columnAdjoiningBorder.style() == BHIDDEN)
1026             return 0;
1027         if (columnAdjoiningBorder.style() > BHIDDEN)
1028             borderWidth = std::max(borderWidth, columnAdjoiningBorder.width());
1029         // FIXME: This logic doesn't properly account for the last column in the last column-group case.
1030     }
1031
1032     if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
1033         const BorderValue& sectionAdjoiningBorder = topNonEmptySection->borderAdjoiningTableEnd();
1034         if (sectionAdjoiningBorder.style() == BHIDDEN)
1035             return 0;
1036
1037         if (sectionAdjoiningBorder.style() > BHIDDEN)
1038             borderWidth = std::max(borderWidth, sectionAdjoiningBorder.width());
1039
1040         if (const RenderTableCell* adjoiningEndCell = topNonEmptySection->firstRowCellAdjoiningTableEnd()) {
1041             // FIXME: Make this work with perpendicular and flipped cells.
1042             const BorderValue& endCellAdjoiningBorder = adjoiningEndCell->borderAdjoiningTableEnd();
1043             if (endCellAdjoiningBorder.style() == BHIDDEN)
1044                 return 0;
1045
1046             const BorderValue& firstRowAdjoiningBorder = adjoiningEndCell->row()->borderAdjoiningTableEnd();
1047             if (firstRowAdjoiningBorder.style() == BHIDDEN)
1048                 return 0;
1049
1050             if (endCellAdjoiningBorder.style() > BHIDDEN)
1051                 borderWidth = std::max(borderWidth, endCellAdjoiningBorder.width());
1052             if (firstRowAdjoiningBorder.style() > BHIDDEN)
1053                 borderWidth = std::max(borderWidth, firstRowAdjoiningBorder.width());
1054         }
1055     }
1056     return (borderWidth + (style()->isLeftToRightDirection() ? 1 : 0)) / 2;
1057 }
1058
1059 void RenderTable::recalcBordersInRowDirection()
1060 {
1061     // FIXME: We need to compute the collapsed before / after borders in the same fashion.
1062     m_borderStart = calcBorderStart();
1063     m_borderEnd = calcBorderEnd();
1064 }
1065
1066 int RenderTable::borderBefore() const
1067 {
1068     if (collapseBorders()) {
1069         recalcSectionsIfNeeded();
1070         return outerBorderBefore();
1071     }
1072     return RenderBlock::borderBefore();
1073 }
1074
1075 int RenderTable::borderAfter() const
1076 {
1077     if (collapseBorders()) {
1078         recalcSectionsIfNeeded();
1079         return outerBorderAfter();
1080     }
1081     return RenderBlock::borderAfter();
1082 }
1083
1084 int RenderTable::outerBorderBefore() const
1085 {
1086     if (!collapseBorders())
1087         return 0;
1088     int borderWidth = 0;
1089     if (RenderTableSection* topSection = this->topSection()) {
1090         borderWidth = topSection->outerBorderBefore();
1091         if (borderWidth < 0)
1092             return 0;   // Overridden by hidden
1093     }
1094     const BorderValue& tb = style()->borderBefore();
1095     if (tb.style() == BHIDDEN)
1096         return 0;
1097     if (tb.style() > BHIDDEN)
1098         borderWidth = std::max<int>(borderWidth, tb.width() / 2);
1099     return borderWidth;
1100 }
1101
1102 int RenderTable::outerBorderAfter() const
1103 {
1104     if (!collapseBorders())
1105         return 0;
1106     int borderWidth = 0;
1107
1108     if (RenderTableSection* section = bottomSection()) {
1109         borderWidth = section->outerBorderAfter();
1110         if (borderWidth < 0)
1111             return 0; // Overridden by hidden
1112     }
1113     const BorderValue& tb = style()->borderAfter();
1114     if (tb.style() == BHIDDEN)
1115         return 0;
1116     if (tb.style() > BHIDDEN)
1117         borderWidth = std::max<int>(borderWidth, (tb.width() + 1) / 2);
1118     return borderWidth;
1119 }
1120
1121 int RenderTable::outerBorderStart() const
1122 {
1123     if (!collapseBorders())
1124         return 0;
1125
1126     int borderWidth = 0;
1127
1128     const BorderValue& tb = style()->borderStart();
1129     if (tb.style() == BHIDDEN)
1130         return 0;
1131     if (tb.style() > BHIDDEN)
1132         borderWidth = (tb.width() + (style()->isLeftToRightDirection() ? 0 : 1)) / 2;
1133
1134     bool allHidden = true;
1135     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) {
1136         int sw = section->outerBorderStart();
1137         if (sw < 0)
1138             continue;
1139         allHidden = false;
1140         borderWidth = std::max(borderWidth, sw);
1141     }
1142     if (allHidden)
1143         return 0;
1144
1145     return borderWidth;
1146 }
1147
1148 int RenderTable::outerBorderEnd() const
1149 {
1150     if (!collapseBorders())
1151         return 0;
1152
1153     int borderWidth = 0;
1154
1155     const BorderValue& tb = style()->borderEnd();
1156     if (tb.style() == BHIDDEN)
1157         return 0;
1158     if (tb.style() > BHIDDEN)
1159         borderWidth = (tb.width() + (style()->isLeftToRightDirection() ? 1 : 0)) / 2;
1160
1161     bool allHidden = true;
1162     for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) {
1163         int sw = section->outerBorderEnd();
1164         if (sw < 0)
1165             continue;
1166         allHidden = false;
1167         borderWidth = std::max(borderWidth, sw);
1168     }
1169     if (allHidden)
1170         return 0;
1171
1172     return borderWidth;
1173 }
1174
1175 RenderTableSection* RenderTable::sectionAbove(const RenderTableSection* section, SkipEmptySectionsValue skipEmptySections) const
1176 {
1177     recalcSectionsIfNeeded();
1178
1179     if (section == m_head)
1180         return 0;
1181
1182     RenderObject* prevSection = section == m_foot ? lastChild() : section->previousSibling();
1183     while (prevSection) {
1184         if (prevSection->isTableSection() && prevSection != m_head && prevSection != m_foot && (skipEmptySections == DoNotSkipEmptySections || toRenderTableSection(prevSection)->numRows()))
1185             break;
1186         prevSection = prevSection->previousSibling();
1187     }
1188     if (!prevSection && m_head && (skipEmptySections == DoNotSkipEmptySections || m_head->numRows()))
1189         prevSection = m_head;
1190     return toRenderTableSection(prevSection);
1191 }
1192
1193 RenderTableSection* RenderTable::sectionBelow(const RenderTableSection* section, SkipEmptySectionsValue skipEmptySections) const
1194 {
1195     recalcSectionsIfNeeded();
1196
1197     if (section == m_foot)
1198         return 0;
1199
1200     RenderObject* nextSection = section == m_head ? firstChild() : section->nextSibling();
1201     while (nextSection) {
1202         if (nextSection->isTableSection() && nextSection != m_head && nextSection != m_foot && (skipEmptySections  == DoNotSkipEmptySections || toRenderTableSection(nextSection)->numRows()))
1203             break;
1204         nextSection = nextSection->nextSibling();
1205     }
1206     if (!nextSection && m_foot && (skipEmptySections == DoNotSkipEmptySections || m_foot->numRows()))
1207         nextSection = m_foot;
1208     return toRenderTableSection(nextSection);
1209 }
1210
1211 RenderTableSection* RenderTable::bottomSection() const
1212 {
1213     recalcSectionsIfNeeded();
1214
1215     if (m_foot)
1216         return m_foot;
1217
1218     for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
1219         if (child->isTableSection())
1220             return toRenderTableSection(child);
1221     }
1222
1223     return 0;
1224 }
1225
1226 RenderTableCell* RenderTable::cellAbove(const RenderTableCell* cell) const
1227 {
1228     recalcSectionsIfNeeded();
1229
1230     // Find the section and row to look in
1231     unsigned r = cell->rowIndex();
1232     RenderTableSection* section = 0;
1233     unsigned rAbove = 0;
1234     if (r > 0) {
1235         // cell is not in the first row, so use the above row in its own section
1236         section = cell->section();
1237         rAbove = r - 1;
1238     } else {
1239         section = sectionAbove(cell->section(), SkipEmptySections);
1240         if (section) {
1241             ASSERT(section->numRows());
1242             rAbove = section->numRows() - 1;
1243         }
1244     }
1245
1246     // Look up the cell in the section's grid, which requires effective col index
1247     if (section) {
1248         unsigned effCol = colToEffCol(cell->col());
1249         RenderTableSection::CellStruct& aboveCell = section->cellAt(rAbove, effCol);
1250         return aboveCell.primaryCell();
1251     } else
1252         return 0;
1253 }
1254
1255 RenderTableCell* RenderTable::cellBelow(const RenderTableCell* cell) const
1256 {
1257     recalcSectionsIfNeeded();
1258
1259     // Find the section and row to look in
1260     unsigned r = cell->rowIndex() + cell->rowSpan() - 1;
1261     RenderTableSection* section = 0;
1262     unsigned rBelow = 0;
1263     if (r < cell->section()->numRows() - 1) {
1264         // The cell is not in the last row, so use the next row in the section.
1265         section = cell->section();
1266         rBelow = r + 1;
1267     } else {
1268         section = sectionBelow(cell->section(), SkipEmptySections);
1269         if (section)
1270             rBelow = 0;
1271     }
1272
1273     // Look up the cell in the section's grid, which requires effective col index
1274     if (section) {
1275         unsigned effCol = colToEffCol(cell->col());
1276         RenderTableSection::CellStruct& belowCell = section->cellAt(rBelow, effCol);
1277         return belowCell.primaryCell();
1278     } else
1279         return 0;
1280 }
1281
1282 RenderTableCell* RenderTable::cellBefore(const RenderTableCell* cell) const
1283 {
1284     recalcSectionsIfNeeded();
1285
1286     RenderTableSection* section = cell->section();
1287     unsigned effCol = colToEffCol(cell->col());
1288     if (!effCol)
1289         return 0;
1290
1291     // If we hit a colspan back up to a real cell.
1292     RenderTableSection::CellStruct& prevCell = section->cellAt(cell->rowIndex(), effCol - 1);
1293     return prevCell.primaryCell();
1294 }
1295
1296 RenderTableCell* RenderTable::cellAfter(const RenderTableCell* cell) const
1297 {
1298     recalcSectionsIfNeeded();
1299
1300     unsigned effCol = colToEffCol(cell->col() + cell->colSpan());
1301     if (effCol >= numEffCols())
1302         return 0;
1303     return cell->section()->primaryCellAt(cell->rowIndex(), effCol);
1304 }
1305
1306 int RenderTable::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
1307 {
1308     ASSERT(linePositionMode == PositionOnContainingLine);
1309     int baseline = firstLineBoxBaseline();
1310     if (baseline != -1) {
1311         if (isInline())
1312             return beforeMarginInLineDirection(direction) + baseline;
1313         return baseline;
1314     }
1315
1316     return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
1317 }
1318
1319 int RenderTable::inlineBlockBaseline(LineDirectionMode) const
1320 {
1321     // Tables are skipped when computing an inline-block's baseline.
1322     return -1;
1323 }
1324
1325 int RenderTable::firstLineBoxBaseline() const
1326 {
1327     // The baseline of a 'table' is the same as the 'inline-table' baseline per CSS 3 Flexbox (CSS 2.1
1328     // doesn't define the baseline of a 'table' only an 'inline-table').
1329     // This is also needed to properly determine the baseline of a cell if it has a table child.
1330
1331     if (isWritingModeRoot())
1332         return -1;
1333
1334     recalcSectionsIfNeeded();
1335
1336     const RenderTableSection* topNonEmptySection = this->topNonEmptySection();
1337     if (!topNonEmptySection)
1338         return -1;
1339
1340     int baseline = topNonEmptySection->firstLineBoxBaseline();
1341     if (baseline > 0)
1342         return topNonEmptySection->logicalTop() + baseline;
1343
1344     // FIXME: A table row always has a baseline per CSS 2.1. Will this return the right value?
1345     return -1;
1346 }
1347
1348 LayoutRect RenderTable::overflowClipRect(const LayoutPoint& location, OverlayScrollbarSizeRelevancy relevancy)
1349 {
1350     LayoutRect rect = RenderBlock::overflowClipRect(location, relevancy);
1351
1352     // If we have a caption, expand the clip to include the caption.
1353     // FIXME: Technically this is wrong, but it's virtually impossible to fix this
1354     // for real until captions have been re-written.
1355     // FIXME: This code assumes (like all our other caption code) that only top/bottom are
1356     // supported.  When we actually support left/right and stop mapping them to top/bottom,
1357     // we might have to hack this code first (depending on what order we do these bug fixes in).
1358     if (!m_captions.isEmpty()) {
1359         if (style()->isHorizontalWritingMode()) {
1360             rect.setHeight(height());
1361             rect.setY(location.y());
1362         } else {
1363             rect.setWidth(width());
1364             rect.setX(location.x());
1365         }
1366     }
1367
1368     return rect;
1369 }
1370
1371 bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
1372 {
1373     LayoutPoint adjustedLocation = accumulatedOffset + location();
1374
1375     // Check kids first.
1376     if (!hasOverflowClip() || locationInContainer.intersects(overflowClipRect(adjustedLocation))) {
1377         for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
1378             if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) {
1379                 LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(child), adjustedLocation);
1380                 if (child->nodeAtPoint(request, result, locationInContainer, childPoint, action)) {
1381                     updateHitTestResult(result, toLayoutPoint(locationInContainer.point() - childPoint));
1382                     return true;
1383                 }
1384             }
1385         }
1386     }
1387
1388     // Check our bounds next.
1389     LayoutRect boundsRect(adjustedLocation, size());
1390     if (visibleToHitTestRequest(request) && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && locationInContainer.intersects(boundsRect)) {
1391         updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(adjustedLocation)));
1392         if (!result.addNodeToRectBasedTestResult(node(), request, locationInContainer, boundsRect))
1393             return true;
1394     }
1395
1396     return false;
1397 }
1398
1399 RenderTable* RenderTable::createAnonymousWithParentRenderer(const RenderObject* parent)
1400 {
1401     RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parent->style(), TABLE);
1402     RenderTable* newTable = new RenderTable(0);
1403     newTable->setDocumentForAnonymous(&parent->document());
1404     newTable->setStyle(newStyle.release());
1405     return newTable;
1406 }
1407
1408 const BorderValue& RenderTable::tableStartBorderAdjoiningCell(const RenderTableCell* cell) const
1409 {
1410     ASSERT(cell->isFirstOrLastCellInRow());
1411     if (hasSameDirectionAs(cell->row()))
1412         return style()->borderStart();
1413
1414     return style()->borderEnd();
1415 }
1416
1417 const BorderValue& RenderTable::tableEndBorderAdjoiningCell(const RenderTableCell* cell) const
1418 {
1419     ASSERT(cell->isFirstOrLastCellInRow());
1420     if (hasSameDirectionAs(cell->row()))
1421         return style()->borderEnd();
1422
1423     return style()->borderStart();
1424 }
1425
1426 }