Revert borders to integers for subpixel layout
[WebKit-https.git] / Source / WebCore / 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 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 "RenderTable.h"
28
29 #include "AutoTableLayout.h"
30 #include "CollapsedBorderValue.h"
31 #include "DeleteButtonController.h"
32 #include "Document.h"
33 #include "FixedTableLayout.h"
34 #include "FrameView.h"
35 #include "HitTestResult.h"
36 #include "HTMLNames.h"
37 #include "LayoutRepainter.h"
38 #include "RenderLayer.h"
39 #include "RenderTableCaption.h"
40 #include "RenderTableCell.h"
41 #include "RenderTableCol.h"
42 #include "RenderTableSection.h"
43 #include "RenderView.h"
44
45 using namespace std;
46
47 namespace WebCore {
48
49 using namespace HTMLNames;
50
51 RenderTable::RenderTable(Node* node)
52     : RenderBlock(node)
53     , m_head(0)
54     , m_foot(0)
55     , m_firstBody(0)
56     , m_currentBorder(0)
57     , m_collapsedBordersValid(false)
58     , m_hasColElements(false)
59     , m_needsSectionRecalc(false)
60     , m_hSpacing(0)
61     , m_vSpacing(0)
62     , m_borderStart(0)
63     , m_borderEnd(0)
64 {
65     setChildrenInline(false);
66     m_columnPos.fill(0, 1);
67     
68 }
69
70 RenderTable::~RenderTable()
71 {
72 }
73
74 void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
75 {
76     RenderBlock::styleDidChange(diff, oldStyle);
77     propagateStyleToAnonymousChildren();
78
79     ETableLayout oldTableLayout = oldStyle ? oldStyle->tableLayout() : TAUTO;
80
81     // In the collapsed border model, there is no cell spacing.
82     m_hSpacing = collapseBorders() ? 0 : style()->horizontalBorderSpacing();
83     m_vSpacing = collapseBorders() ? 0 : style()->verticalBorderSpacing();
84     m_columnPos[0] = m_hSpacing;
85
86     if (!m_tableLayout || style()->tableLayout() != oldTableLayout) {
87         // According to the CSS2 spec, you only use fixed table layout if an
88         // explicit width is specified on the table.  Auto width implies auto table layout.
89         if (style()->tableLayout() == TFIXED && !style()->logicalWidth().isAuto())
90             m_tableLayout = adoptPtr(new FixedTableLayout(this));
91         else
92             m_tableLayout = adoptPtr(new AutoTableLayout(this));
93     }
94
95     // If border was changed, invalidate collapsed borders cache.
96     if (!needsLayout() && oldStyle && oldStyle->border() != style()->border())
97         invalidateCollapsedBorders();
98 }
99
100 static inline void resetSectionPointerIfNotBefore(RenderTableSection*& ptr, RenderObject* before)
101 {
102     if (!before || !ptr)
103         return;
104     RenderObject* o = before->previousSibling();
105     while (o && o != ptr)
106         o = o->previousSibling();
107     if (!o)
108         ptr = 0;
109 }
110
111 void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
112 {
113     // Make sure we don't append things after :after-generated content if we have it.
114     if (!beforeChild)
115         beforeChild = afterPseudoElementRenderer();
116
117     bool wrapInAnonymousSection = !child->isPositioned();
118
119     if (child->isTableCaption()) {
120         m_captions.append(toRenderTableCaption(child));
121         setNeedsSectionRecalc();
122         wrapInAnonymousSection = false;
123     } else if (child->isTableCol()) {
124         m_hasColElements = true;
125         wrapInAnonymousSection = false;
126     } else if (child->isTableSection()) {
127         switch (child->style()->display()) {
128             case TABLE_HEADER_GROUP:
129                 resetSectionPointerIfNotBefore(m_head, beforeChild);
130                 if (!m_head) {
131                     m_head = toRenderTableSection(child);
132                 } else {
133                     resetSectionPointerIfNotBefore(m_firstBody, beforeChild);
134                     if (!m_firstBody) 
135                         m_firstBody = toRenderTableSection(child);
136                 }
137                 wrapInAnonymousSection = false;
138                 break;
139             case TABLE_FOOTER_GROUP:
140                 resetSectionPointerIfNotBefore(m_foot, beforeChild);
141                 if (!m_foot) {
142                     m_foot = toRenderTableSection(child);
143                     wrapInAnonymousSection = false;
144                     break;
145                 }
146                 // Fall through.
147             case TABLE_ROW_GROUP:
148                 resetSectionPointerIfNotBefore(m_firstBody, beforeChild);
149                 if (!m_firstBody)
150                     m_firstBody = toRenderTableSection(child);
151                 wrapInAnonymousSection = false;
152                 break;
153             default:
154                 ASSERT_NOT_REACHED();
155         }
156     } else if (child->isTableCell() || child->isTableRow())
157         wrapInAnonymousSection = true;
158     else
159         wrapInAnonymousSection = true;
160
161     if (!wrapInAnonymousSection) {
162         // If the next renderer is actually wrapped in an anonymous table section, we need to go up and find that.
163         while (beforeChild && beforeChild->parent() != this)
164             beforeChild = beforeChild->parent();
165
166         RenderBox::addChild(child, beforeChild);
167         return;
168     }
169
170     if (!beforeChild && lastChild() && lastChild()->isTableSection() && lastChild()->isAnonymous() && !lastChild()->isBeforeContent()) {
171         lastChild()->addChild(child);
172         return;
173     }
174
175     if (beforeChild && !beforeChild->isAnonymous() && beforeChild->parent() == this) {
176         RenderObject* section = beforeChild->previousSibling();
177         if (section && section->isTableSection() && section->isAnonymous()) {
178             section->addChild(child);
179             return;
180         }
181     }
182
183     RenderObject* lastBox = beforeChild;
184     while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableSection() && lastBox->style()->display() != TABLE_CAPTION && lastBox->style()->display() != TABLE_COLUMN_GROUP)
185         lastBox = lastBox->parent();
186     if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox)) {
187         if (beforeChild == lastBox)
188             beforeChild = lastBox->firstChild();
189         lastBox->addChild(child, beforeChild);
190         return;
191     }
192
193     if (beforeChild && !beforeChild->isTableSection() && beforeChild->style()->display() != TABLE_CAPTION && beforeChild->style()->display() != TABLE_COLUMN_GROUP)
194         beforeChild = 0;
195     RenderTableSection* section = new (renderArena()) RenderTableSection(document() /* anonymous */);
196     RefPtr<RenderStyle> newStyle = RenderStyle::create();
197     newStyle->inheritFrom(style());
198     newStyle->setDisplay(TABLE_ROW_GROUP);
199     section->setStyle(newStyle.release());
200     addChild(section, beforeChild);
201     section->addChild(child);
202 }
203
204 void RenderTable::removeChild(RenderObject* oldChild)
205 {
206     RenderBox::removeChild(oldChild);
207  
208     size_t index = m_captions.find(oldChild);
209     if (index != notFound) {
210         m_captions.remove(index);
211         if (node())
212             node()->setNeedsStyleRecalc();
213     }
214     setNeedsSectionRecalc();
215 }
216
217 void RenderTable::computeLogicalWidth()
218 {
219     recalcSectionsIfNeeded();
220
221     if (isPositioned())
222         computePositionedLogicalWidth();
223
224     RenderBlock* cb = containingBlock();
225
226     LayoutUnit availableLogicalWidth = containingBlockLogicalWidthForContent();
227     bool hasPerpendicularContainingBlock = cb->style()->isHorizontalWritingMode() != style()->isHorizontalWritingMode();
228     LayoutUnit containerWidthInInlineDirection = hasPerpendicularContainingBlock ? perpendicularContainingBlockLogicalHeight() : availableLogicalWidth;
229
230     Length styleLogicalWidth = style()->logicalWidth();
231     if (styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive())
232         setLogicalWidth(convertStyleLogicalWidthToComputedWidth(styleLogicalWidth, containerWidthInInlineDirection));
233     else {
234         // Subtract out any fixed margins from our available width for auto width tables.
235         LayoutUnit marginStart = style()->marginStart().calcMinValue(availableLogicalWidth);
236         LayoutUnit marginEnd = style()->marginEnd().calcMinValue(availableLogicalWidth);
237         LayoutUnit marginTotal = marginStart + marginEnd;
238         
239         // Subtract out our margins to get the available content width.
240         LayoutUnit availableContentLogicalWidth = max<LayoutUnit>(0, containerWidthInInlineDirection - marginTotal);
241         if (shrinkToAvoidFloats() && cb->containsFloats() && !hasPerpendicularContainingBlock) {
242             // FIXME: Work with regions someday.
243             availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, cb, 0, 0);
244         }
245
246         // Ensure we aren't bigger than our available width.
247         setLogicalWidth(min(availableContentLogicalWidth, maxPreferredLogicalWidth()));
248     }
249
250     // Ensure we aren't smaller than our min preferred width.
251     setLogicalWidth(max(logicalWidth(), minPreferredLogicalWidth()));
252
253     // Ensure we aren't smaller than our min-width style.
254     Length styleMinLogicalWidth = style()->logicalMinWidth();
255     if (styleMinLogicalWidth.isSpecified() && styleMinLogicalWidth.isPositive())
256         setLogicalWidth(max(logicalWidth(), convertStyleLogicalWidthToComputedWidth(styleMinLogicalWidth, availableLogicalWidth)));
257
258     // Finally, with our true width determined, compute our margins for real.
259     setMarginStart(0);
260     setMarginEnd(0);
261     if (!hasPerpendicularContainingBlock)
262         computeInlineDirectionMargins(cb, availableLogicalWidth, logicalWidth());
263     else {
264         setMarginStart(style()->marginStart().calcMinValue(availableLogicalWidth));
265         setMarginEnd(style()->marginEnd().calcMinValue(availableLogicalWidth));
266     }
267 }
268
269 // This method takes a RenderStyle's logical width, min-width, or max-width length and computes its actual value.
270 LayoutUnit RenderTable::convertStyleLogicalWidthToComputedWidth(const Length& styleLogicalWidth, LayoutUnit availableWidth)
271 {
272     // HTML tables' width styles already include borders and paddings, but CSS tables' width styles do not.
273     int borders = 0;
274     bool isCSSTable = !node() || !node()->hasTagName(tableTag);
275     if (isCSSTable && styleLogicalWidth.isFixed() && styleLogicalWidth.isPositive()) {
276         recalcBordersInRowDirection();
277         borders = borderStart() + borderEnd() + (collapseBorders() ? 0 : paddingStart() + paddingEnd());
278     }
279     return styleLogicalWidth.calcMinValue(availableWidth) + borders;
280 }
281
282 void RenderTable::layoutCaption(RenderTableCaption* caption)
283 {
284     IntRect captionRect(caption->x(), caption->y(), caption->width(), caption->height());
285
286     if (caption->needsLayout()) {
287         // The margins may not be available but ensure the caption is at least located beneath any previous sibling caption
288         // so that it does not mistakenly think any floats in the previous caption intrude into it.
289         caption->setLogicalLocation(IntPoint(caption->marginStart(), caption->marginBefore() + logicalHeight()));
290         // If RenderTableCaption ever gets a layout() function, use it here.
291         caption->layoutIfNeeded();
292     }
293     // Apply the margins to the location now that they are definitely available from layout
294     caption->setLogicalLocation(IntPoint(caption->marginStart(), caption->marginBefore() + logicalHeight()));
295
296     if (!selfNeedsLayout() && caption->checkForRepaintDuringLayout())
297         caption->repaintDuringLayoutIfMoved(captionRect);
298
299     setLogicalHeight(logicalHeight() + caption->logicalHeight() + caption->marginBefore() + caption->marginAfter());
300 }
301
302 void RenderTable::layout()
303 {
304     ASSERT(needsLayout());
305
306     if (simplifiedLayout())
307         return;
308
309     recalcSectionsIfNeeded();
310         
311     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
312     LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
313
314     setLogicalHeight(0);
315     m_overflow.clear();
316
317     initMaxMarginValues();
318     
319     LayoutUnit oldLogicalWidth = logicalWidth();
320     computeLogicalWidth();
321
322     if (logicalWidth() != oldLogicalWidth) {
323         for (unsigned i = 0; i < m_captions.size(); i++)
324             m_captions[i]->setNeedsLayout(true, false);
325     }
326     // FIXME: The optimisation below doesn't work since the internal table
327     // layout could have changed.  we need to add a flag to the table
328     // layout that tells us if something has changed in the min max
329     // calculations to do it correctly.
330 //     if ( oldWidth != width() || columns.size() + 1 != columnPos.size() )
331     m_tableLayout->layout();
332
333     setCellLogicalWidths();
334
335     LayoutUnit totalSectionLogicalHeight = 0;
336     LayoutUnit oldTableLogicalTop = 0;
337     for (unsigned i = 0; i < m_captions.size(); i++)
338         oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
339
340     bool collapsing = collapseBorders();
341
342     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
343         if (child->isTableSection()) {
344             child->layoutIfNeeded();
345             RenderTableSection* section = toRenderTableSection(child);
346             totalSectionLogicalHeight += section->calcRowLogicalHeight();
347             if (collapsing)
348                 section->recalcOuterBorder();
349             ASSERT(!section->needsLayout());
350         } else if (child->isTableCol()) {
351             child->layoutIfNeeded();
352             ASSERT(!child->needsLayout());
353         }
354     }
355
356     // If any table section moved vertically, we will just repaint everything from that
357     // section down (it is quite unlikely that any of the following sections
358     // did not shift).
359     bool sectionMoved = false;
360     LayoutUnit movedSectionLogicalTop = 0;
361
362     // FIXME: Collapse caption margin.
363     if (!m_captions.isEmpty()) {
364         for (unsigned i = 0; i < m_captions.size(); i++) {
365             if (m_captions[i]->style()->captionSide() == CAPBOTTOM)
366                 continue;
367             layoutCaption(m_captions[i]);
368         }
369         if (logicalHeight() != oldTableLogicalTop) {
370             sectionMoved = true;
371             movedSectionLogicalTop = min(logicalHeight(), oldTableLogicalTop);
372         }
373     }
374
375     LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? zeroLayoutUnit : paddingBefore());
376     LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? zeroLayoutUnit : paddingAfter());
377
378     setLogicalHeight(logicalHeight() + borderAndPaddingBefore);
379
380     if (!isPositioned())
381         computeLogicalHeight();
382
383     Length logicalHeightLength = style()->logicalHeight();
384     LayoutUnit computedLogicalHeight = 0;
385     if (logicalHeightLength.isFixed()) {
386         // HTML tables size as though CSS height includes border/padding, CSS tables do not.
387         LayoutUnit borders = node() && node()->hasTagName(tableTag) ? (borderAndPaddingBefore + borderAndPaddingAfter) : zeroLayoutUnit;
388         computedLogicalHeight = logicalHeightLength.value() - borders;
389     } else if (logicalHeightLength.isPercent())
390         computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength);
391     computedLogicalHeight = max<LayoutUnit>(0, computedLogicalHeight);
392
393     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
394         if (child->isTableSection())
395             // FIXME: Distribute the extra logical height between all table sections instead of giving it all to the first one.
396             toRenderTableSection(child)->layoutRows(child == topSection() ? max<LayoutUnit>(0, computedLogicalHeight - totalSectionLogicalHeight) : 0);
397     }
398
399     if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
400         // Completely empty tables (with no sections or anything) should at least honor specified height
401         // in strict mode.
402         setLogicalHeight(logicalHeight() + computedLogicalHeight);
403     }
404
405     LayoutUnit sectionLogicalLeft = style()->isLeftToRightDirection() ? borderStart() : borderEnd();
406     if (!collapsing)
407         sectionLogicalLeft += style()->isLeftToRightDirection() ? paddingStart() : paddingEnd();
408
409     // position the table sections
410     RenderTableSection* section = topSection();
411     while (section) {
412         if (!sectionMoved && section->logicalTop() != logicalHeight()) {
413             sectionMoved = true;
414             movedSectionLogicalTop = min(logicalHeight(), section->logicalTop()) + (style()->isHorizontalWritingMode() ? section->minYVisualOverflow() : section->minXVisualOverflow());
415         }
416         section->setLogicalLocation(LayoutPoint(sectionLogicalLeft, logicalHeight()));
417
418         setLogicalHeight(logicalHeight() + section->logicalHeight());
419         section = sectionBelow(section);
420     }
421
422     setLogicalHeight(logicalHeight() + borderAndPaddingAfter);
423
424     for (unsigned i = 0; i < m_captions.size(); i++) {
425         if (m_captions[i]->style()->captionSide() != CAPBOTTOM)
426             continue;
427         layoutCaption(m_captions[i]);
428     }
429
430     if (isPositioned())
431         computeLogicalHeight();
432
433     // table can be containing block of positioned elements.
434     // FIXME: Only pass true if width or height changed.
435     layoutPositionedObjects(true);
436
437     updateLayerTransform();
438
439     // Layout was changed, so probably borders too.
440     invalidateCollapsedBorders();
441
442     computeOverflow(clientLogicalBottom());
443
444     statePusher.pop();
445
446     if (view()->layoutState()->pageLogicalHeight())
447         setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(logicalTop()));
448
449     bool didFullRepaint = repainter.repaintAfterLayout();
450     // Repaint with our new bounds if they are different from our old bounds.
451     if (!didFullRepaint && sectionMoved) {
452         if (style()->isHorizontalWritingMode())
453             repaintRectangle(LayoutRect(minXVisualOverflow(), movedSectionLogicalTop, maxXVisualOverflow() - minXVisualOverflow(), maxYVisualOverflow() - movedSectionLogicalTop));
454         else
455             repaintRectangle(LayoutRect(movedSectionLogicalTop, minYVisualOverflow(), maxXVisualOverflow() - movedSectionLogicalTop, maxYVisualOverflow() - minYVisualOverflow()));
456     }
457
458     setNeedsLayout(false);
459 }
460
461 // Collect all the unique border values that we want to paint in a sorted list.
462 void RenderTable::recalcCollapsedBorders()
463 {
464     if (m_collapsedBordersValid)
465         return;
466     m_collapsedBordersValid = true;
467     m_collapsedBorders.clear();
468     for (RenderObject* section = firstChild(); section; section = section->nextSibling()) {
469         if (!section->isTableSection())
470             continue;
471         for (RenderObject* row = section->firstChild(); row; row = row->nextSibling()) {
472             if (!row->isTableRow())
473                 continue;
474             for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
475                 if (!cell->isTableCell())
476                     continue;
477                 ASSERT(toRenderTableCell(cell)->table() == this);
478                 toRenderTableCell(cell)->collectBorderValues(m_collapsedBorders);
479             }
480         }
481     }
482     RenderTableCell::sortBorderValues(m_collapsedBorders);
483 }
484
485
486 void RenderTable::addOverflowFromChildren()
487 {
488     // Add overflow from borders.
489     // Technically it's odd that we are incorporating the borders into layout overflow, which is only supposed to be about overflow from our
490     // descendant objects, but since tables don't support overflow:auto, this works out fine.
491     if (collapseBorders()) {
492         int rightBorderOverflow = width() + outerBorderRight() - borderRight();
493         int leftBorderOverflow = borderLeft() - outerBorderLeft();
494         int bottomBorderOverflow = height() + outerBorderBottom() - borderBottom();
495         int topBorderOverflow = borderTop() - outerBorderTop();
496         IntRect borderOverflowRect(leftBorderOverflow, topBorderOverflow, rightBorderOverflow - leftBorderOverflow, bottomBorderOverflow - topBorderOverflow);
497         if (borderOverflowRect != borderBoxRect()) {
498             addLayoutOverflow(borderOverflowRect);
499             addVisualOverflow(borderOverflowRect);
500         }
501     }
502
503     // Add overflow from our caption.
504     for (unsigned i = 0; i < m_captions.size(); i++) 
505         addOverflowFromChild(m_captions[i]);
506
507     // Add overflow from our sections.
508     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
509         if (child->isTableSection()) {
510             RenderTableSection* section = toRenderTableSection(child);
511             addOverflowFromChild(section);
512         }
513     }
514 }
515
516 void RenderTable::setCellLogicalWidths()
517 {
518     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
519         if (child->isTableSection())
520             toRenderTableSection(child)->setCellLogicalWidths();
521     }
522 }
523
524 void RenderTable::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
525 {
526     LayoutPoint adjustedPaintOffset = paintOffset + location();
527
528     PaintPhase paintPhase = paintInfo.phase;
529
530     if (!isRoot()) {
531         LayoutRect overflowBox = visualOverflowRect();
532         flipForWritingMode(overflowBox);
533         overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
534         overflowBox.moveBy(adjustedPaintOffset);
535         if (!overflowBox.intersects(paintInfo.rect))
536             return;
537     }
538
539     bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset);
540     paintObject(paintInfo, adjustedPaintOffset);
541     if (pushedClip)
542         popContentsClip(paintInfo, paintPhase, adjustedPaintOffset);
543 }
544
545 void RenderTable::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
546 {
547     PaintPhase paintPhase = paintInfo.phase;
548     if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && hasBoxDecorations() && style()->visibility() == VISIBLE)
549         paintBoxDecorations(paintInfo, paintOffset);
550
551     if (paintPhase == PaintPhaseMask) {
552         paintMask(paintInfo, paintOffset);
553         return;
554     }
555
556     // We're done.  We don't bother painting any children.
557     if (paintPhase == PaintPhaseBlockBackground)
558         return;
559     
560     // We don't paint our own background, but we do let the kids paint their backgrounds.
561     if (paintPhase == PaintPhaseChildBlockBackgrounds)
562         paintPhase = PaintPhaseChildBlockBackground;
563
564     PaintInfo info(paintInfo);
565     info.phase = paintPhase;
566     info.updatePaintingRootForChildren(this);
567
568     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
569         if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) {
570             LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(child), paintOffset);
571             child->paint(info, childPoint);
572         }
573     }
574     
575     if (collapseBorders() && paintPhase == PaintPhaseChildBlockBackground && style()->visibility() == VISIBLE) {
576         recalcCollapsedBorders();
577         // Using our cached sorted styles, we then do individual passes,
578         // painting each style of border from lowest precedence to highest precedence.
579         info.phase = PaintPhaseCollapsedTableBorders;
580         size_t count = m_collapsedBorders.size();
581         for (size_t i = 0; i < count; ++i) {
582             m_currentBorder = &m_collapsedBorders[i];
583             for (RenderObject* child = firstChild(); child; child = child->nextSibling())
584                 if (child->isTableSection()) {
585                     LayoutPoint childPoint = flipForWritingModeForChild(toRenderTableSection(child), paintOffset);
586                     child->paint(info, childPoint);
587                 }
588         }
589         m_currentBorder = 0;
590     }
591
592     // Paint outline.
593     if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && hasOutline() && style()->visibility() == VISIBLE)
594         paintOutline(paintInfo.context, LayoutRect(paintOffset, size()));
595 }
596
597 void RenderTable::subtractCaptionRect(LayoutRect& rect) const
598 {
599     for (unsigned i = 0; i < m_captions.size(); i++) {
600         LayoutUnit captionLogicalHeight = m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
601         bool captionIsBefore = (m_captions[i]->style()->captionSide() != CAPBOTTOM) ^ style()->isFlippedBlocksWritingMode();
602         if (style()->isHorizontalWritingMode()) {
603             rect.setHeight(rect.height() - captionLogicalHeight);
604             if (captionIsBefore)
605                 rect.move(0, captionLogicalHeight);
606         } else {
607             rect.setWidth(rect.width() - captionLogicalHeight);
608             if (captionIsBefore)
609                 rect.move(captionLogicalHeight, 0);
610         }
611     }
612 }
613
614 void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
615 {
616     if (!paintInfo.shouldPaintWithinRoot(this))
617         return;
618
619     LayoutRect rect(paintOffset, size());
620     subtractCaptionRect(rect);
621
622     if (!boxShadowShouldBeAppliedToBackground(determineBackgroundBleedAvoidance(paintInfo.context)))
623         paintBoxShadow(paintInfo, rect, style(), Normal);
624     paintBackground(paintInfo, rect);
625     paintBoxShadow(paintInfo, rect, style(), Inset);
626
627     if (style()->hasBorder() && !collapseBorders())
628         paintBorder(paintInfo, rect, style());
629 }
630
631 void RenderTable::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
632 {
633     if (style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
634         return;
635
636     LayoutRect rect(paintOffset, size());
637     subtractCaptionRect(rect);
638
639     paintMaskImages(paintInfo, rect);
640 }
641
642 void RenderTable::computePreferredLogicalWidths()
643 {
644     ASSERT(preferredLogicalWidthsDirty());
645
646     recalcSectionsIfNeeded();
647     recalcBordersInRowDirection();
648
649     m_tableLayout->computePreferredLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
650
651     for (unsigned i = 0; i < m_captions.size(); i++)
652         m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_captions[i]->minPreferredLogicalWidth());
653
654     setPreferredLogicalWidthsDirty(false);
655 }
656
657 RenderTableSection* RenderTable::topNonEmptySection() const
658 {
659     RenderTableSection* section = topSection();
660     if (section && !section->numRows())
661         section = sectionBelow(section, SkipEmptySections);
662     return section;
663 }
664
665 void RenderTable::splitColumn(unsigned position, unsigned firstSpan)
666 {
667     // we need to add a new columnStruct
668     unsigned oldSize = m_columns.size();
669     m_columns.grow(oldSize + 1);
670     unsigned oldSpan = m_columns[position].span;
671     ASSERT(oldSpan > firstSpan);
672     m_columns[position].span = firstSpan;
673     memmove(m_columns.data() + position + 1, m_columns.data() + position, (oldSize - position) * sizeof(ColumnStruct));
674     m_columns[position + 1].span = oldSpan - firstSpan;
675
676     // Propagate the change in our columns representation to the sections that don't need
677     // cell recalc. If they do, they will be synced up directly with m_columns later.
678     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
679         if (!child->isTableSection())
680             continue;
681
682         RenderTableSection* section = toRenderTableSection(child);
683         if (section->needsCellRecalc())
684             continue;
685
686         section->splitColumn(position, firstSpan);
687     }
688
689     m_columnPos.grow(numEffCols() + 1);
690     setNeedsLayoutAndPrefWidthsRecalc();
691 }
692
693 void RenderTable::appendColumn(unsigned span)
694 {
695     unsigned pos = m_columns.size();
696     unsigned newSize = pos + 1;
697     m_columns.grow(newSize);
698     m_columns[pos].span = span;
699
700     // Propagate the change in our columns representation to the sections that don't need
701     // cell recalc. If they do, they will be synced up directly with m_columns later.
702     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
703         if (!child->isTableSection())
704             continue;
705
706         RenderTableSection* section = toRenderTableSection(child);
707         if (section->needsCellRecalc())
708             continue;
709
710         section->appendColumn(pos);
711     }
712
713     m_columnPos.grow(numEffCols() + 1);
714     setNeedsLayoutAndPrefWidthsRecalc();
715 }
716
717 RenderTableCol* RenderTable::nextColElement(RenderTableCol* current) const
718 {
719     RenderObject* next = current->firstChild();
720     if (!next)
721         next = current->nextSibling();
722     if (!next && current->parent()->isTableCol())
723         next = current->parent()->nextSibling();
724
725     while (next) {
726         if (next->isTableCol())
727             return toRenderTableCol(next);
728         if (!m_captions.contains(next))
729             return 0;
730         next = next->nextSibling();
731     }
732     
733     return 0;
734 }
735
736 RenderTableCol* RenderTable::colElement(unsigned col, bool* startEdge, bool* endEdge) const
737 {
738     if (!m_hasColElements)
739         return 0;
740     RenderObject* child = firstChild();
741     unsigned cCol = 0;
742
743     while (child) {
744         if (child->isTableCol())
745             break;
746         if (!m_captions.contains(child))
747             return 0;
748         child = child->nextSibling();
749     }
750     if (!child)
751         return 0;
752
753     RenderTableCol* colElem = toRenderTableCol(child);
754     while (colElem) {
755         unsigned span = colElem->span();
756         if (!colElem->firstChild()) {
757             unsigned startCol = cCol;
758             ASSERT(span >= 1);
759             unsigned endCol = cCol + span - 1;
760             cCol += span;
761             if (cCol > col) {
762                 if (startEdge)
763                     *startEdge = startCol == col;
764                 if (endEdge)
765                     *endEdge = endCol == col;
766                 return colElem;
767             }
768         }
769         colElem = nextColElement(colElem);
770     }
771
772     return 0;
773 }
774
775 void RenderTable::recalcSections() const
776 {
777     m_head = 0;
778     m_foot = 0;
779     m_firstBody = 0;
780     m_hasColElements = false;
781
782     // We need to get valid pointers to caption, head, foot and first body again
783     RenderObject* nextSibling;
784     for (RenderObject* child = firstChild(); child; child = nextSibling) {
785         nextSibling = child->nextSibling();
786         switch (child->style()->display()) {
787             case TABLE_COLUMN:
788             case TABLE_COLUMN_GROUP:
789                 m_hasColElements = true;
790                 break;
791             case TABLE_HEADER_GROUP:
792                 if (child->isTableSection()) {
793                     RenderTableSection* section = toRenderTableSection(child);
794                     if (!m_head)
795                         m_head = section;
796                     else if (!m_firstBody)
797                         m_firstBody = section;
798                     section->recalcCellsIfNeeded();
799                 }
800                 break;
801             case TABLE_FOOTER_GROUP:
802                 if (child->isTableSection()) {
803                     RenderTableSection* section = toRenderTableSection(child);
804                     if (!m_foot)
805                         m_foot = section;
806                     else if (!m_firstBody)
807                         m_firstBody = section;
808                     section->recalcCellsIfNeeded();
809                 }
810                 break;
811             case TABLE_ROW_GROUP:
812                 if (child->isTableSection()) {
813                     RenderTableSection* section = toRenderTableSection(child);
814                     if (!m_firstBody)
815                         m_firstBody = section;
816                     section->recalcCellsIfNeeded();
817                 }
818                 break;
819             default:
820                 break;
821         }
822     }
823
824     // repair column count (addChild can grow it too much, because it always adds elements to the last row of a section)
825     unsigned maxCols = 0;
826     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
827         if (child->isTableSection()) {
828             RenderTableSection* section = toRenderTableSection(child);
829             unsigned sectionCols = section->numColumns();
830             if (sectionCols > maxCols)
831                 maxCols = sectionCols;
832         }
833     }
834     
835     m_columns.resize(maxCols);
836     m_columnPos.resize(maxCols + 1);
837
838     ASSERT(selfNeedsLayout());
839
840     m_needsSectionRecalc = false;
841 }
842
843 int RenderTable::calcBorderStart() const
844 {
845     if (collapseBorders()) {
846         // Determined by the first cell of the first row. See the CSS 2.1 spec, section 17.6.2.
847         if (!numEffCols())
848             return 0;
849
850         unsigned borderWidth = 0;
851
852         const BorderValue& tb = style()->borderStart();
853         if (tb.style() == BHIDDEN)
854             return 0;
855         if (tb.style() > BHIDDEN)
856             borderWidth = tb.width();
857
858         if (RenderTableCol* colGroup = colElement(0)) {
859             const BorderValue& gb = colGroup->style()->borderStart();
860             if (gb.style() == BHIDDEN)
861                 return 0;
862             if (gb.style() > BHIDDEN)
863                 borderWidth = max(borderWidth, gb.width());
864         }
865         
866         if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
867             const BorderValue& sb = topNonEmptySection->style()->borderStart();
868             if (sb.style() == BHIDDEN)
869                 return 0;
870
871             if (sb.style() > BHIDDEN)
872                 borderWidth = max(borderWidth, sb.width());
873
874             const RenderTableSection::CellStruct& cs = topNonEmptySection->cellAt(0, 0);
875             
876             if (cs.hasCells()) {
877                 const BorderValue& cb = cs.primaryCell()->style()->borderStart(); // FIXME: Make this work with perpendicualr and flipped cells.
878                 if (cb.style() == BHIDDEN)
879                     return 0;
880
881                 const BorderValue& rb = cs.primaryCell()->parent()->style()->borderStart();
882                 if (rb.style() == BHIDDEN)
883                     return 0;
884
885                 if (cb.style() > BHIDDEN)
886                     borderWidth = max(borderWidth, cb.width());
887                 if (rb.style() > BHIDDEN)
888                     borderWidth = max(borderWidth, rb.width());
889             }
890         }
891         return (borderWidth + (style()->isLeftToRightDirection() ? 0 : 1)) / 2;
892     }
893     return RenderBlock::borderStart();
894 }
895
896 int RenderTable::calcBorderEnd() const
897 {
898     if (collapseBorders()) {
899         // Determined by the last cell of the first row. See the CSS 2.1 spec, section 17.6.2.
900         if (!numEffCols())
901             return 0;
902
903         unsigned borderWidth = 0;
904
905         const BorderValue& tb = style()->borderEnd();
906         if (tb.style() == BHIDDEN)
907             return 0;
908         if (tb.style() > BHIDDEN)
909             borderWidth = tb.width();
910
911         unsigned endColumn = numEffCols() - 1;
912         if (RenderTableCol* colGroup = colElement(endColumn)) {
913             const BorderValue& gb = colGroup->style()->borderEnd();
914             if (gb.style() == BHIDDEN)
915                 return 0;
916             if (gb.style() > BHIDDEN)
917                 borderWidth = max(borderWidth, gb.width());
918         }
919
920         if (const RenderTableSection* topNonEmptySection = this->topNonEmptySection()) {
921             const BorderValue& sb = topNonEmptySection->style()->borderEnd();
922             if (sb.style() == BHIDDEN)
923                 return 0;
924
925             if (sb.style() > BHIDDEN)
926                 borderWidth = max(borderWidth, sb.width());
927
928             const RenderTableSection::CellStruct& cs = topNonEmptySection->cellAt(0, endColumn);
929             
930             if (cs.hasCells()) {
931                 const BorderValue& cb = cs.primaryCell()->style()->borderEnd(); // FIXME: Make this work with perpendicular and flipped cells.
932                 if (cb.style() == BHIDDEN)
933                     return 0;
934
935                 const BorderValue& rb = cs.primaryCell()->parent()->style()->borderEnd();
936                 if (rb.style() == BHIDDEN)
937                     return 0;
938
939                 if (cb.style() > BHIDDEN)
940                     borderWidth = max(borderWidth, cb.width());
941                 if (rb.style() > BHIDDEN)
942                     borderWidth = max(borderWidth, rb.width());
943             }
944         }
945         return (borderWidth + (style()->isLeftToRightDirection() ? 1 : 0)) / 2;
946     }
947     return RenderBlock::borderEnd();
948 }
949
950 void RenderTable::recalcBordersInRowDirection()
951 {
952     m_borderStart = calcBorderStart();
953     m_borderEnd = calcBorderEnd();
954 }
955
956 int RenderTable::borderBefore() const
957 {
958     if (collapseBorders()) {
959         recalcSectionsIfNeeded();
960         return outerBorderBefore();
961     }
962     return RenderBlock::borderBefore();
963 }
964
965 int RenderTable::borderAfter() const
966 {
967     if (collapseBorders()) {
968         recalcSectionsIfNeeded();
969         return outerBorderAfter();
970     }
971     return RenderBlock::borderAfter();
972 }
973
974 int RenderTable::outerBorderBefore() const
975 {
976     if (!collapseBorders())
977         return 0;
978     int borderWidth = 0;
979     if (RenderTableSection* topSection = this->topSection()) {
980         borderWidth = topSection->outerBorderBefore();
981         if (borderWidth < 0)
982             return 0;   // Overridden by hidden
983     }
984     const BorderValue& tb = style()->borderBefore();
985     if (tb.style() == BHIDDEN)
986         return 0;
987     if (tb.style() > BHIDDEN)
988         borderWidth = max<int>(borderWidth, tb.width() / 2);
989     return borderWidth;
990 }
991
992 int RenderTable::outerBorderAfter() const
993 {
994     if (!collapseBorders())
995         return 0;
996     int borderWidth = 0;
997     RenderTableSection* bottomSection;
998     if (m_foot)
999         bottomSection = m_foot;
1000     else {
1001         RenderObject* child;
1002         for (child = lastChild(); child && !child->isTableSection(); child = child->previousSibling()) { }
1003         bottomSection = child ? toRenderTableSection(child) : 0;
1004     }
1005     if (bottomSection) {
1006         borderWidth = bottomSection->outerBorderAfter();
1007         if (borderWidth < 0)
1008             return 0;   // Overridden by hidden
1009     }
1010     const BorderValue& tb = style()->borderAfter();
1011     if (tb.style() == BHIDDEN)
1012         return 0;
1013     if (tb.style() > BHIDDEN)
1014         borderWidth = max<int>(borderWidth, (tb.width() + 1) / 2);
1015     return borderWidth;
1016 }
1017
1018 int RenderTable::outerBorderStart() const
1019 {
1020     if (!collapseBorders())
1021         return 0;
1022
1023     int borderWidth = 0;
1024
1025     const BorderValue& tb = style()->borderStart();
1026     if (tb.style() == BHIDDEN)
1027         return 0;
1028     if (tb.style() > BHIDDEN)
1029         borderWidth = (tb.width() + (style()->isLeftToRightDirection() ? 0 : 1)) / 2;
1030
1031     bool allHidden = true;
1032     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
1033         if (!child->isTableSection())
1034             continue;
1035         int sw = toRenderTableSection(child)->outerBorderStart();
1036         if (sw < 0)
1037             continue;
1038         allHidden = false;
1039         borderWidth = max(borderWidth, sw);
1040     }
1041     if (allHidden)
1042         return 0;
1043
1044     return borderWidth;
1045 }
1046
1047 int RenderTable::outerBorderEnd() const
1048 {
1049     if (!collapseBorders())
1050         return 0;
1051
1052     int borderWidth = 0;
1053
1054     const BorderValue& tb = style()->borderEnd();
1055     if (tb.style() == BHIDDEN)
1056         return 0;
1057     if (tb.style() > BHIDDEN)
1058         borderWidth = (tb.width() + (style()->isLeftToRightDirection() ? 1 : 0)) / 2;
1059
1060     bool allHidden = true;
1061     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
1062         if (!child->isTableSection())
1063             continue;
1064         int sw = toRenderTableSection(child)->outerBorderEnd();
1065         if (sw < 0)
1066             continue;
1067         allHidden = false;
1068         borderWidth = max(borderWidth, sw);
1069     }
1070     if (allHidden)
1071         return 0;
1072
1073     return borderWidth;
1074 }
1075
1076 RenderTableSection* RenderTable::sectionAbove(const RenderTableSection* section, SkipEmptySectionsValue skipEmptySections) const
1077 {
1078     recalcSectionsIfNeeded();
1079
1080     if (section == m_head)
1081         return 0;
1082
1083     RenderObject* prevSection = section == m_foot ? lastChild() : section->previousSibling();
1084     while (prevSection) {
1085         if (prevSection->isTableSection() && prevSection != m_head && prevSection != m_foot && (skipEmptySections == DoNotSkipEmptySections || toRenderTableSection(prevSection)->numRows()))
1086             break;
1087         prevSection = prevSection->previousSibling();
1088     }
1089     if (!prevSection && m_head && (skipEmptySections == DoNotSkipEmptySections || m_head->numRows()))
1090         prevSection = m_head;
1091     return toRenderTableSection(prevSection);
1092 }
1093
1094 RenderTableSection* RenderTable::sectionBelow(const RenderTableSection* section, SkipEmptySectionsValue skipEmptySections) const
1095 {
1096     recalcSectionsIfNeeded();
1097
1098     if (section == m_foot)
1099         return 0;
1100
1101     RenderObject* nextSection = section == m_head ? firstChild() : section->nextSibling();
1102     while (nextSection) {
1103         if (nextSection->isTableSection() && nextSection != m_head && nextSection != m_foot && (skipEmptySections  == DoNotSkipEmptySections || toRenderTableSection(nextSection)->numRows()))
1104             break;
1105         nextSection = nextSection->nextSibling();
1106     }
1107     if (!nextSection && m_foot && (skipEmptySections == DoNotSkipEmptySections || m_foot->numRows()))
1108         nextSection = m_foot;
1109     return toRenderTableSection(nextSection);
1110 }
1111
1112 RenderTableCell* RenderTable::cellAbove(const RenderTableCell* cell) const
1113 {
1114     recalcSectionsIfNeeded();
1115
1116     // Find the section and row to look in
1117     unsigned r = cell->row();
1118     RenderTableSection* section = 0;
1119     unsigned rAbove = 0;
1120     if (r > 0) {
1121         // cell is not in the first row, so use the above row in its own section
1122         section = cell->section();
1123         rAbove = r - 1;
1124     } else {
1125         section = sectionAbove(cell->section(), SkipEmptySections);
1126         if (section) {
1127             ASSERT(section->numRows());
1128             rAbove = section->numRows() - 1;
1129         }
1130     }
1131
1132     // Look up the cell in the section's grid, which requires effective col index
1133     if (section) {
1134         unsigned effCol = colToEffCol(cell->col());
1135         RenderTableSection::CellStruct& aboveCell = section->cellAt(rAbove, effCol);
1136         return aboveCell.primaryCell();
1137     } else
1138         return 0;
1139 }
1140
1141 RenderTableCell* RenderTable::cellBelow(const RenderTableCell* cell) const
1142 {
1143     recalcSectionsIfNeeded();
1144
1145     // Find the section and row to look in
1146     unsigned r = cell->row() + cell->rowSpan() - 1;
1147     RenderTableSection* section = 0;
1148     unsigned rBelow = 0;
1149     if (r < cell->section()->numRows() - 1) {
1150         // The cell is not in the last row, so use the next row in the section.
1151         section = cell->section();
1152         rBelow = r + 1;
1153     } else {
1154         section = sectionBelow(cell->section(), SkipEmptySections);
1155         if (section)
1156             rBelow = 0;
1157     }
1158
1159     // Look up the cell in the section's grid, which requires effective col index
1160     if (section) {
1161         unsigned effCol = colToEffCol(cell->col());
1162         RenderTableSection::CellStruct& belowCell = section->cellAt(rBelow, effCol);
1163         return belowCell.primaryCell();
1164     } else
1165         return 0;
1166 }
1167
1168 RenderTableCell* RenderTable::cellBefore(const RenderTableCell* cell) const
1169 {
1170     recalcSectionsIfNeeded();
1171
1172     RenderTableSection* section = cell->section();
1173     unsigned effCol = colToEffCol(cell->col());
1174     if (!effCol)
1175         return 0;
1176     
1177     // If we hit a colspan back up to a real cell.
1178     RenderTableSection::CellStruct& prevCell = section->cellAt(cell->row(), effCol - 1);
1179     return prevCell.primaryCell();
1180 }
1181
1182 RenderTableCell* RenderTable::cellAfter(const RenderTableCell* cell) const
1183 {
1184     recalcSectionsIfNeeded();
1185
1186     unsigned effCol = colToEffCol(cell->col() + cell->colSpan());
1187     if (effCol >= numEffCols())
1188         return 0;
1189     return cell->section()->primaryCellAt(cell->row(), effCol);
1190 }
1191
1192 RenderBlock* RenderTable::firstLineBlock() const
1193 {
1194     return 0;
1195 }
1196
1197 void RenderTable::updateFirstLetter()
1198 {
1199 }
1200
1201 LayoutUnit RenderTable::firstLineBoxBaseline() const
1202 {
1203     if (isWritingModeRoot())
1204         return -1;
1205
1206     recalcSectionsIfNeeded();
1207
1208     const RenderTableSection* topNonEmptySection = this->topNonEmptySection();
1209     if (!topNonEmptySection)
1210         return -1;
1211
1212     return topNonEmptySection->logicalTop() + topNonEmptySection->firstLineBoxBaseline();
1213 }
1214
1215 LayoutRect RenderTable::overflowClipRect(const LayoutPoint& location, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy)
1216 {
1217     LayoutRect rect = RenderBlock::overflowClipRect(location, region, relevancy);
1218     
1219     // If we have a caption, expand the clip to include the caption.
1220     // FIXME: Technically this is wrong, but it's virtually impossible to fix this
1221     // for real until captions have been re-written.
1222     // FIXME: This code assumes (like all our other caption code) that only top/bottom are
1223     // supported.  When we actually support left/right and stop mapping them to top/bottom,
1224     // we might have to hack this code first (depending on what order we do these bug fixes in).
1225     if (!m_captions.isEmpty()) {
1226         if (style()->isHorizontalWritingMode()) {
1227             rect.setHeight(height());
1228             rect.setY(location.y());
1229         } else {
1230             rect.setWidth(width());
1231             rect.setX(location.x());
1232         }
1233     }
1234
1235     return rect;
1236 }
1237
1238 bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
1239 {
1240     LayoutPoint adjustedLocation = accumulatedOffset + location();
1241
1242     // Check kids first.
1243     if (!hasOverflowClip() || overflowClipRect(adjustedLocation, result.region()).intersects(result.rectForPoint(pointInContainer))) {
1244         for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
1245             if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) {
1246                 LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(child), adjustedLocation);
1247                 if (child->nodeAtPoint(request, result, pointInContainer, childPoint, action)) {
1248                     updateHitTestResult(result, toLayoutPoint(pointInContainer - childPoint));
1249                     return true;
1250                 }
1251             }
1252         }
1253     }
1254
1255     // Check our bounds next.
1256     LayoutRect boundsRect(adjustedLocation, size());
1257     if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && boundsRect.intersects(result.rectForPoint(pointInContainer))) {
1258         updateHitTestResult(result, flipForWritingMode(pointInContainer - toLayoutSize(adjustedLocation)));
1259         if (!result.addNodeToRectBasedTestResult(node(), pointInContainer, boundsRect))
1260             return true;
1261     }
1262
1263     return false;
1264 }
1265
1266 }