2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Simon Hausmann <hausmann@kde.org>
4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de)
5 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
25 #include "RenderFrameSet.h"
29 #include "EventHandler.h"
30 #include "EventNames.h"
32 #include "FrameView.h"
33 #include "GraphicsContext.h"
34 #include "HTMLFrameSetElement.h"
35 #include "HitTestRequest.h"
36 #include "HitTestResult.h"
37 #include "MouseEvent.h"
38 #include "PaintInfo.h"
39 #include "RenderFrame.h"
40 #include "RenderLayer.h"
41 #include "RenderView.h"
46 RenderFrameSet::RenderFrameSet(HTMLFrameSetElement* frameSet)
49 , m_isChildResizing(false)
54 RenderFrameSet::~RenderFrameSet()
58 RenderFrameSet::GridAxis::GridAxis()
59 : m_splitBeingResized(noSplit)
63 inline HTMLFrameSetElement* RenderFrameSet::frameSet() const
65 return static_cast<HTMLFrameSetElement*>(node());
68 static Color borderStartEdgeColor()
70 return Color(170, 170, 170);
73 static Color borderEndEdgeColor()
78 static Color borderFillColor()
80 return Color(208, 208, 208);
83 void RenderFrameSet::paintColumnBorder(const PaintInfo& paintInfo, const IntRect& borderRect)
85 if (!paintInfo.rect.intersects(borderRect))
88 // FIXME: We should do something clever when borders from distinct framesets meet at a join.
91 GraphicsContext* context = paintInfo.context;
92 ColorSpace colorSpace = style()->colorSpace();
93 context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->visitedDependentColor(CSSPropertyBorderLeftColor) : borderFillColor(), colorSpace);
95 // Now stroke the edges but only if we have enough room to paint both edges with a little
96 // bit of the fill color showing through.
97 if (borderRect.width() >= 3) {
98 context->fillRect(IntRect(borderRect.location(), IntSize(1, height())), borderStartEdgeColor(), colorSpace);
99 context->fillRect(IntRect(IntPoint(borderRect.maxX() - 1, borderRect.y()), IntSize(1, height())), borderEndEdgeColor(), colorSpace);
103 void RenderFrameSet::paintRowBorder(const PaintInfo& paintInfo, const IntRect& borderRect)
105 if (!paintInfo.rect.intersects(borderRect))
108 // FIXME: We should do something clever when borders from distinct framesets meet at a join.
111 GraphicsContext* context = paintInfo.context;
112 ColorSpace colorSpace = style()->colorSpace();
113 context->fillRect(borderRect, frameSet()->hasBorderColor() ? style()->visitedDependentColor(CSSPropertyBorderLeftColor) : borderFillColor(), colorSpace);
115 // Now stroke the edges but only if we have enough room to paint both edges with a little
116 // bit of the fill color showing through.
117 if (borderRect.height() >= 3) {
118 context->fillRect(IntRect(borderRect.location(), IntSize(width(), 1)), borderStartEdgeColor(), colorSpace);
119 context->fillRect(IntRect(IntPoint(borderRect.x(), borderRect.maxY() - 1), IntSize(width(), 1)), borderEndEdgeColor(), colorSpace);
123 void RenderFrameSet::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
125 if (paintInfo.phase != PaintPhaseForeground)
128 RenderObject* child = firstChild();
132 LayoutPoint adjustedPaintOffset = paintOffset + location();
134 int rows = frameSet()->totalRows();
135 int cols = frameSet()->totalCols();
136 LayoutUnit borderThickness = frameSet()->border();
139 for (int r = 0; r < rows; r++) {
141 for (int c = 0; c < cols; c++) {
142 child->paint(paintInfo, adjustedPaintOffset);
143 xPos += m_cols.m_sizes[c];
144 if (borderThickness && m_cols.m_allowBorder[c + 1]) {
145 paintColumnBorder(paintInfo, pixelSnappedIntRect(LayoutRect(adjustedPaintOffset.x() + xPos, adjustedPaintOffset.y() + yPos, borderThickness, height())));
146 xPos += borderThickness;
148 child = child->nextSibling();
152 yPos += m_rows.m_sizes[r];
153 if (borderThickness && m_rows.m_allowBorder[r + 1]) {
154 paintRowBorder(paintInfo, pixelSnappedIntRect(LayoutRect(adjustedPaintOffset.x(), adjustedPaintOffset.y() + yPos, width(), borderThickness)));
155 yPos += borderThickness;
160 bool RenderFrameSet::nodeAtPoint(const HitTestRequest& request, HitTestResult& result,
161 const HitTestPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
163 if (action != HitTestForeground)
166 bool inside = RenderBox::nodeAtPoint(request, result, pointInContainer, accumulatedOffset, action)
169 if (inside && frameSet()->noResize()
170 && !request.readOnly() && !result.innerNode() && !request.touchMove()) {
171 result.setInnerNode(node());
172 result.setInnerNonSharedNode(node());
175 return inside || m_isChildResizing;
178 void RenderFrameSet::GridAxis::resize(int size)
180 m_sizes.resize(size);
181 m_deltas.resize(size);
184 // To track edges for resizability and borders, we need to be (size + 1). This is because a parent frameset
185 // may ask us for information about our left/top/right/bottom edges in order to make its own decisions about
186 // what to do. We are capable of tainting that parent frameset's borders, so we have to cache this info.
187 m_preventResize.resize(size + 1);
188 m_allowBorder.resize(size + 1);
191 void RenderFrameSet::layOutAxis(GridAxis& axis, const Length* grid, int availableLen)
193 availableLen = max(availableLen, 0);
195 int* gridLayout = axis.m_sizes.data();
198 gridLayout[0] = availableLen;
202 int gridLen = axis.m_sizes.size();
205 int totalRelative = 0;
207 int totalPercent = 0;
208 int countRelative = 0;
210 int countPercent = 0;
212 // First we need to investigate how many columns of each type we have and
213 // how much space these columns are going to require.
214 for (int i = 0; i < gridLen; ++i) {
215 // Count the total length of all of the fixed columns/rows -> totalFixed
216 // Count the number of columns/rows which are fixed -> countFixed
217 if (grid[i].isFixed()) {
218 gridLayout[i] = max(grid[i].intValue(), 0);
219 totalFixed += gridLayout[i];
223 // Count the total percentage of all of the percentage columns/rows -> totalPercent
224 // Count the number of columns/rows which are percentages -> countPercent
225 if (grid[i].isPercent()) {
226 gridLayout[i] = max(intValueForLength(grid[i], availableLen), 0);
227 totalPercent += gridLayout[i];
231 // Count the total relative of all the relative columns/rows -> totalRelative
232 // Count the number of columns/rows which are relative -> countRelative
233 if (grid[i].isRelative()) {
234 totalRelative += max(grid[i].intValue(), 1);
239 int remainingLen = availableLen;
241 // Fixed columns/rows are our first priority. If there is not enough space to fit all fixed
242 // columns/rows we need to proportionally adjust their size.
243 if (totalFixed > remainingLen) {
244 int remainingFixed = remainingLen;
246 for (int i = 0; i < gridLen; ++i) {
247 if (grid[i].isFixed()) {
248 gridLayout[i] = (gridLayout[i] * remainingFixed) / totalFixed;
249 remainingLen -= gridLayout[i];
253 remainingLen -= totalFixed;
255 // Percentage columns/rows are our second priority. Divide the remaining space proportionally
256 // over all percentage columns/rows. IMPORTANT: the size of each column/row is not relative
257 // to 100%, but to the total percentage. For example, if there are three columns, each of 75%,
258 // and the available space is 300px, each column will become 100px in width.
259 if (totalPercent > remainingLen) {
260 int remainingPercent = remainingLen;
262 for (int i = 0; i < gridLen; ++i) {
263 if (grid[i].isPercent()) {
264 gridLayout[i] = (gridLayout[i] * remainingPercent) / totalPercent;
265 remainingLen -= gridLayout[i];
269 remainingLen -= totalPercent;
271 // Relative columns/rows are our last priority. Divide the remaining space proportionally
272 // over all relative columns/rows. IMPORTANT: the relative value of 0* is treated as 1*.
274 int lastRelative = 0;
275 int remainingRelative = remainingLen;
277 for (int i = 0; i < gridLen; ++i) {
278 if (grid[i].isRelative()) {
279 gridLayout[i] = (max(grid[i].intValue(), 1) * remainingRelative) / totalRelative;
280 remainingLen -= gridLayout[i];
285 // If we could not evenly distribute the available space of all of the relative
286 // columns/rows, the remainder will be added to the last column/row.
287 // For example: if we have a space of 100px and three columns (*,*,*), the remainder will
288 // be 1px and will be added to the last column: 33px, 33px, 34px.
290 gridLayout[lastRelative] += remainingLen;
295 // If we still have some left over space we need to divide it over the already existing
298 // Our first priority is to spread if over the percentage columns. The remaining
299 // space is spread evenly, for example: if we have a space of 100px, the columns
300 // definition of 25%,25% used to result in two columns of 25px. After this the
301 // columns will each be 50px in width.
302 if (countPercent && totalPercent) {
303 int remainingPercent = remainingLen;
304 int changePercent = 0;
306 for (int i = 0; i < gridLen; ++i) {
307 if (grid[i].isPercent()) {
308 changePercent = (remainingPercent * gridLayout[i]) / totalPercent;
309 gridLayout[i] += changePercent;
310 remainingLen -= changePercent;
313 } else if (totalFixed) {
314 // Our last priority is to spread the remaining space over the fixed columns.
315 // For example if we have 100px of space and two column of each 40px, both
316 // columns will become exactly 50px.
317 int remainingFixed = remainingLen;
320 for (int i = 0; i < gridLen; ++i) {
321 if (grid[i].isFixed()) {
322 changeFixed = (remainingFixed * gridLayout[i]) / totalFixed;
323 gridLayout[i] += changeFixed;
324 remainingLen -= changeFixed;
330 // If we still have some left over space we probably ended up with a remainder of
331 // a division. We cannot spread it evenly anymore. If we have any percentage
332 // columns/rows simply spread the remainder equally over all available percentage columns,
333 // regardless of their size.
334 if (remainingLen && countPercent) {
335 int remainingPercent = remainingLen;
336 int changePercent = 0;
338 for (int i = 0; i < gridLen; ++i) {
339 if (grid[i].isPercent()) {
340 changePercent = remainingPercent / countPercent;
341 gridLayout[i] += changePercent;
342 remainingLen -= changePercent;
345 } else if (remainingLen && countFixed) {
346 // If we don't have any percentage columns/rows we only have
347 // fixed columns. Spread the remainder equally over all fixed
349 int remainingFixed = remainingLen;
352 for (int i = 0; i < gridLen; ++i) {
353 if (grid[i].isFixed()) {
354 changeFixed = remainingFixed / countFixed;
355 gridLayout[i] += changeFixed;
356 remainingLen -= changeFixed;
361 // Still some left over. Add it to the last column, because it is impossible
362 // spread it evenly or equally.
364 gridLayout[gridLen - 1] += remainingLen;
366 // now we have the final layout, distribute the delta over it
368 int* gridDelta = axis.m_deltas.data();
369 for (int i = 0; i < gridLen; ++i) {
370 if (gridLayout[i] && gridLayout[i] + gridDelta[i] <= 0)
372 gridLayout[i] += gridDelta[i];
374 // if the deltas broke something, undo them
376 for (int i = 0; i < gridLen; ++i)
377 gridLayout[i] -= gridDelta[i];
378 axis.m_deltas.fill(0);
382 void RenderFrameSet::notifyFrameEdgeInfoChanged()
386 // FIXME: We should only recompute the edge info with respect to the frame that changed
387 // and its adjacent frame(s) instead of recomputing the edge info for the entire frameset.
391 void RenderFrameSet::fillFromEdgeInfo(const FrameEdgeInfo& edgeInfo, int r, int c)
393 if (edgeInfo.allowBorder(LeftFrameEdge))
394 m_cols.m_allowBorder[c] = true;
395 if (edgeInfo.allowBorder(RightFrameEdge))
396 m_cols.m_allowBorder[c + 1] = true;
397 if (edgeInfo.preventResize(LeftFrameEdge))
398 m_cols.m_preventResize[c] = true;
399 if (edgeInfo.preventResize(RightFrameEdge))
400 m_cols.m_preventResize[c + 1] = true;
402 if (edgeInfo.allowBorder(TopFrameEdge))
403 m_rows.m_allowBorder[r] = true;
404 if (edgeInfo.allowBorder(BottomFrameEdge))
405 m_rows.m_allowBorder[r + 1] = true;
406 if (edgeInfo.preventResize(TopFrameEdge))
407 m_rows.m_preventResize[r] = true;
408 if (edgeInfo.preventResize(BottomFrameEdge))
409 m_rows.m_preventResize[r + 1] = true;
412 void RenderFrameSet::computeEdgeInfo()
414 m_rows.m_preventResize.fill(frameSet()->noResize());
415 m_rows.m_allowBorder.fill(false);
416 m_cols.m_preventResize.fill(frameSet()->noResize());
417 m_cols.m_allowBorder.fill(false);
419 RenderObject* child = firstChild();
423 int rows = frameSet()->totalRows();
424 int cols = frameSet()->totalCols();
425 for (int r = 0; r < rows; ++r) {
426 for (int c = 0; c < cols; ++c) {
427 FrameEdgeInfo edgeInfo;
428 if (child->isFrameSet())
429 edgeInfo = toRenderFrameSet(child)->edgeInfo();
431 edgeInfo = toRenderFrame(child)->edgeInfo();
432 fillFromEdgeInfo(edgeInfo, r, c);
433 child = child->nextSibling();
440 FrameEdgeInfo RenderFrameSet::edgeInfo() const
442 FrameEdgeInfo result(frameSet()->noResize(), true);
444 int rows = frameSet()->totalRows();
445 int cols = frameSet()->totalCols();
447 result.setPreventResize(LeftFrameEdge, m_cols.m_preventResize[0]);
448 result.setAllowBorder(LeftFrameEdge, m_cols.m_allowBorder[0]);
449 result.setPreventResize(RightFrameEdge, m_cols.m_preventResize[cols]);
450 result.setAllowBorder(RightFrameEdge, m_cols.m_allowBorder[cols]);
451 result.setPreventResize(TopFrameEdge, m_rows.m_preventResize[0]);
452 result.setAllowBorder(TopFrameEdge, m_rows.m_allowBorder[0]);
453 result.setPreventResize(BottomFrameEdge, m_rows.m_preventResize[rows]);
454 result.setAllowBorder(BottomFrameEdge, m_rows.m_allowBorder[rows]);
460 void RenderFrameSet::layout()
462 ASSERT(needsLayout());
464 bool doFullRepaint = selfNeedsLayout() && checkForRepaintDuringLayout();
465 LayoutRect oldBounds;
467 oldBounds = absoluteClippedOverflowRect();
469 if (!parent()->isFrameSet() && !document()->printing()) {
470 setWidth(view()->viewWidth());
471 setHeight(view()->viewHeight());
474 unsigned cols = frameSet()->totalCols();
475 unsigned rows = frameSet()->totalRows();
477 if (m_rows.m_sizes.size() != rows || m_cols.m_sizes.size() != cols) {
482 LayoutUnit borderThickness = frameSet()->border();
483 layOutAxis(m_rows, frameSet()->rowLengths(), height() - (rows - 1) * borderThickness);
484 layOutAxis(m_cols, frameSet()->colLengths(), width() - (cols - 1) * borderThickness);
486 if (flattenFrameSet())
487 positionFramesWithFlattening();
496 view()->repaintViewRectangle(oldBounds);
497 LayoutRect newBounds = absoluteClippedOverflowRect();
498 if (newBounds != oldBounds)
499 view()->repaintViewRectangle(newBounds);
502 // If this FrameSet has a transform matrix then we need to recompute it
503 // because the transform origin is a function the size of the RenderFrameSet
504 // which may not be computed until it is attached to the render tree.
505 if (layer() && hasTransform())
506 layer()->updateTransform();
508 setNeedsLayout(false);
511 void RenderFrameSet::positionFrames()
513 RenderBox* child = firstChildBox();
517 int rows = frameSet()->totalRows();
518 int cols = frameSet()->totalCols();
521 int borderThickness = frameSet()->border();
522 for (int r = 0; r < rows; r++) {
524 int height = m_rows.m_sizes[r];
525 for (int c = 0; c < cols; c++) {
526 child->setLocation(IntPoint(xPos, yPos));
527 int width = m_cols.m_sizes[c];
529 // has to be resized and itself resize its contents
530 if (width != child->width() || height != child->height()) {
531 child->setWidth(width);
532 child->setHeight(height);
533 child->setNeedsLayout(true);
537 xPos += width + borderThickness;
539 child = child->nextSiblingBox();
543 yPos += height + borderThickness;
546 // all the remaining frames are hidden to avoid ugly spurious unflowed frames
547 for (; child; child = child->nextSiblingBox()) {
550 child->setNeedsLayout(false);
554 void RenderFrameSet::positionFramesWithFlattening()
556 RenderBox* child = firstChildBox();
560 int rows = frameSet()->totalRows();
561 int cols = frameSet()->totalCols();
563 int borderThickness = frameSet()->border();
564 bool repaintNeeded = false;
566 // calculate frameset height based on actual content height to eliminate scrolling
568 for (int r = 0; r < rows && !out; r++) {
570 int height = m_rows.m_sizes[r];
572 for (int c = 0; c < cols; c++) {
573 IntRect oldFrameRect = pixelSnappedIntRect(child->frameRect());
575 int width = m_cols.m_sizes[c];
577 bool fixedWidth = frameSet()->colLengths() && frameSet()->colLengths()[c].isFixed();
578 bool fixedHeight = frameSet()->rowLengths() && frameSet()->rowLengths()[r].isFixed();
580 // has to be resized and itself resize its contents
582 child->setWidth(width ? width + extra / (cols - c) : 0);
584 child->setWidth(width);
585 child->setHeight(height);
587 child->setNeedsLayout(true);
589 if (child->isFrameSet())
590 toRenderFrameSet(child)->layout();
592 toRenderFrame(child)->layoutWithFlattening(fixedWidth, fixedHeight);
594 if (child->height() > m_rows.m_sizes[r])
595 m_rows.m_sizes[r] = child->height();
596 if (child->width() > m_cols.m_sizes[c])
597 m_cols.m_sizes[c] = child->width();
599 if (child->frameRect() != oldFrameRect)
600 repaintNeeded = true;
602 // difference between calculated frame width and the width it actually decides to have
603 extra += width - m_cols.m_sizes[c];
605 child = child->nextSiblingBox();
616 child = firstChildBox();
617 for (int r = 0; r < rows && !out; r++) {
619 for (int c = 0; c < cols; c++) {
620 // ensure the rows and columns are filled
621 IntRect oldRect = pixelSnappedIntRect(child->frameRect());
623 child->setLocation(IntPoint(xPos, yPos));
624 child->setHeight(m_rows.m_sizes[r]);
625 child->setWidth(m_cols.m_sizes[c]);
627 if (child->frameRect() != oldRect) {
628 repaintNeeded = true;
630 // update to final size
631 child->setNeedsLayout(true);
632 if (child->isFrameSet())
633 toRenderFrameSet(child)->layout();
635 toRenderFrame(child)->layoutWithFlattening(true, true);
638 xPos += m_cols.m_sizes[c] + borderThickness;
639 child = child->nextSiblingBox();
645 yPos += m_rows.m_sizes[r] + borderThickness;
648 setWidth(xPos - borderThickness);
649 setHeight(yPos - borderThickness);
654 // all the remaining frames are hidden to avoid ugly spurious unflowed frames
655 for (; child; child = child->nextSiblingBox()) {
658 child->setNeedsLayout(false);
662 bool RenderFrameSet::flattenFrameSet() const
664 return frame() && frame()->settings() && frame()->settings()->frameFlatteningEnabled();
667 void RenderFrameSet::startResizing(GridAxis& axis, int position)
669 int split = hitTestSplit(axis, position);
670 if (split == noSplit || axis.m_preventResize[split]) {
671 axis.m_splitBeingResized = noSplit;
674 axis.m_splitBeingResized = split;
675 axis.m_splitResizeOffset = position - splitPosition(axis, split);
678 void RenderFrameSet::continueResizing(GridAxis& axis, int position)
682 if (axis.m_splitBeingResized == noSplit)
684 int currentSplitPosition = splitPosition(axis, axis.m_splitBeingResized);
685 int delta = (position - currentSplitPosition) - axis.m_splitResizeOffset;
688 axis.m_deltas[axis.m_splitBeingResized - 1] += delta;
689 axis.m_deltas[axis.m_splitBeingResized] -= delta;
690 setNeedsLayout(true);
693 bool RenderFrameSet::userResize(MouseEvent* evt)
695 if (flattenFrameSet())
701 if (evt->type() == eventNames().mousedownEvent && evt->button() == LeftButton) {
702 FloatPoint localPos = absoluteToLocal(evt->absoluteLocation(), false, true);
703 startResizing(m_cols, localPos.x());
704 startResizing(m_rows, localPos.y());
705 if (m_cols.m_splitBeingResized != noSplit || m_rows.m_splitBeingResized != noSplit) {
711 if (evt->type() == eventNames().mousemoveEvent || (evt->type() == eventNames().mouseupEvent && evt->button() == LeftButton)) {
712 FloatPoint localPos = absoluteToLocal(evt->absoluteLocation(), false, true);
713 continueResizing(m_cols, localPos.x());
714 continueResizing(m_rows, localPos.y());
715 if (evt->type() == eventNames().mouseupEvent && evt->button() == LeftButton) {
716 setIsResizing(false);
725 void RenderFrameSet::setIsResizing(bool isResizing)
727 m_isResizing = isResizing;
728 for (RenderObject* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
729 if (ancestor->isFrameSet())
730 toRenderFrameSet(ancestor)->m_isChildResizing = isResizing;
732 if (Frame* frame = this->frame())
733 frame->eventHandler()->setResizingFrameSet(isResizing ? frameSet() : 0);
736 bool RenderFrameSet::isResizingRow() const
738 return m_isResizing && m_rows.m_splitBeingResized != noSplit;
741 bool RenderFrameSet::isResizingColumn() const
743 return m_isResizing && m_cols.m_splitBeingResized != noSplit;
746 bool RenderFrameSet::canResizeRow(const IntPoint& p) const
748 int r = hitTestSplit(m_rows, p.y());
749 return r != noSplit && !m_rows.m_preventResize[r];
752 bool RenderFrameSet::canResizeColumn(const IntPoint& p) const
754 int c = hitTestSplit(m_cols, p.x());
755 return c != noSplit && !m_cols.m_preventResize[c];
758 int RenderFrameSet::splitPosition(const GridAxis& axis, int split) const
763 int borderThickness = frameSet()->border();
765 int size = axis.m_sizes.size();
770 for (int i = 0; i < split && i < size; ++i)
771 position += axis.m_sizes[i] + borderThickness;
772 return position - borderThickness;
775 int RenderFrameSet::hitTestSplit(const GridAxis& axis, int position) const
780 int borderThickness = frameSet()->border();
781 if (borderThickness <= 0)
784 size_t size = axis.m_sizes.size();
788 int splitPosition = axis.m_sizes[0];
789 for (size_t i = 1; i < size; ++i) {
790 if (position >= splitPosition && position < splitPosition + borderThickness)
792 splitPosition += borderThickness + axis.m_sizes[i];
797 bool RenderFrameSet::isChildAllowed(RenderObject* child, RenderStyle*) const
799 return child->isFrame() || child->isFrameSet();
802 CursorDirective RenderFrameSet::getCursor(const LayoutPoint& point, Cursor& cursor) const
804 IntPoint roundedPoint = roundedIntPoint(point);
805 if (canResizeRow(roundedPoint)) {
806 cursor = rowResizeCursor();
809 if (canResizeColumn(roundedPoint)) {
810 cursor = columnResizeCursor();
813 return RenderBox::getCursor(point, cursor);
816 } // namespace WebCore