summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderTableSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/RenderTableSection.cpp')
-rw-r--r--WebCore/rendering/RenderTableSection.cpp107
1 files changed, 77 insertions, 30 deletions
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index e192e29..8cb54c0 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -25,7 +25,6 @@
#include "config.h"
#include "RenderTableSection.h"
-
#include "CachedImage.h"
#include "Document.h"
#include "HitTestResult.h"
@@ -1116,38 +1115,43 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, int tx, int ty)
// If some cell overflows, just paint all of them.
if (!m_hasOverflowingCell) {
- for (; startrow < totalRows; startrow++) {
- if (ty + m_rowPos[startrow + 1] >= y - os)
- break;
- }
- if (startrow == totalRows && ty + m_rowPos[totalRows] + table()->outerBorderBottom() >= y - os)
- startrow--;
+ int relativeY = y - ty;
+ int top = relativeY - os;
+ // binary search to find a row
+ startrow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), top) - m_rowPos.begin();
+
+ // The binary search above gives us the first row with
+ // a y position >= the top of the paint rect. Thus, the previous
+ // may need to be repainted as well.
+ if (startrow == m_rowPos.size() || (startrow > 0 && (m_rowPos[startrow] > top)))
+ --startrow;
+
+ int bottom = relativeY + h + os - 1;
+ endrow = std::lower_bound(m_rowPos.begin(), m_rowPos.end(), bottom) - m_rowPos.begin();
+ if ((endrow == m_rowPos.size()) || (endrow > 0 && m_rowPos[endrow - 1] == bottom))
+ --endrow;
- for (; endrow > 0; endrow--) {
- if (ty + m_rowPos[endrow - 1] <= y + h + os)
- break;
- }
if (!endrow && ty + m_rowPos[0] - table()->outerBorderTop() <= y + h + os)
- endrow++;
+ ++endrow;
}
-
unsigned startcol = 0;
unsigned endcol = totalCols;
// FIXME: Implement RTL.
if (!m_hasOverflowingCell && style()->direction() == LTR) {
- for (; startcol < totalCols; startcol++) {
- if (tx + table()->columnPositions()[startcol + 1] >= x - os)
- break;
- }
- if (startcol == totalCols && tx + table()->columnPositions()[totalCols] + table()->outerBorderRight() >= x - os)
- startcol--;
+ int relativeX = x - tx;
+ int left = relativeX - os;
+ Vector<int>& columnPos = table()->columnPositions();
+ startcol = std::lower_bound(columnPos.begin(), columnPos.end(), left) - columnPos.begin();
+ if ((startcol == columnPos.size()) || (startcol > 0 && (columnPos[startcol] > left)))
+ --startcol;
+
+ int right = relativeX + w + os - 1;
+ endcol = std::lower_bound(columnPos.begin(), columnPos.end(), right) - columnPos.begin();
+ if (endcol == columnPos.size() || (endcol > 0 && (columnPos[endcol - 1] == right)))
+ --endcol;
- for (; endcol > 0; endcol--) {
- if (tx + table()->columnPositions()[endcol - 1] <= x + w + os)
- break;
- }
if (!endcol && tx + table()->columnPositions()[0] - table()->outerBorderLeft() <= y + w + os)
- endcol++;
+ ++endcol;
}
#ifdef ANDROID_LAYOUT
@@ -1282,6 +1286,10 @@ void RenderTableSection::splitColumn(int pos, int first)
// Hit Testing
bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int xPos, int yPos, int tx, int ty, HitTestAction action)
{
+ // If we have no children then we have nothing to do.
+ if (!firstChild())
+ return false;
+
// Table sections cannot ever be hit tested. Effectively they do not exist.
// Just forward to our children always.
tx += x();
@@ -1290,17 +1298,56 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
if (hasOverflowClip() && !overflowClipRect(tx, ty).intersects(result.rectFromPoint(xPos, yPos)))
return false;
- for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
- // FIXME: We have to skip over inline flows, since they can show up inside table rows
- // at the moment (a demoted inline <form> for example). If we ever implement a
- // table-specific hit-test method (which we should do for performance reasons anyway),
- // then we can remove this check.
- if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ if (m_hasOverflowingCell) {
+ for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
+ // FIXME: We have to skip over inline flows, since they can show up inside table rows
+ // at the moment (a demoted inline <form> for example). If we ever implement a
+ // table-specific hit-test method (which we should do for performance reasons anyway),
+ // then we can remove this check.
+ if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
+ updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ int relativeY = yPos - ty;
+ // leftrow corresponds to the first row that starts after the y mouse position
+ unsigned leftrow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), relativeY) - m_rowPos.begin();
+ if (leftrow == m_rowPos.size())
+ return false;
+ // Grab the last row that starts before the y mouse position.
+ if (leftrow > 0)
+ --leftrow;
+
+ Vector<int>& columnPos = table()->columnPositions();
+ bool rtl = style()->direction() == RTL;
+ int relativeX = xPos - tx;
+ if (rtl)
+ relativeX = columnPos[columnPos.size() - 1] - relativeX;
+
+ unsigned leftcol = std::lower_bound(columnPos.begin(), columnPos.end(), relativeX) - columnPos.begin();
+ if (leftcol == columnPos.size())
+ return false;
+ if (leftcol > 0)
+ --leftcol;
+
+ CellStruct& current = cellAt(leftrow, leftcol);
+
+ // If the cell is empty, there's nothing to do
+ if (!current.hasCells())
+ return false;
+
+ for (int i = current.cells.size() - 1; i >= 0; --i) {
+ RenderTableCell* cell = current.cells[i];
+ if (static_cast<RenderObject*>(cell)->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
return true;
}
}
return false;
+
}
} // namespace WebCore