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 HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
163
if (action != HitTestForeground)
166
bool inside = RenderBox::nodeAtPoint(request, result, locationInContainer, 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
StackStats::LayoutCheckPoint layoutCheckPoint;
463
ASSERT(needsLayout());
465
bool doFullRepaint = selfNeedsLayout() && checkForRepaintDuringLayout();
466
LayoutRect oldBounds;
468
oldBounds = absoluteClippedOverflowRect();
470
if (!parent()->isFrameSet() && !document()->printing()) {
471
setWidth(view()->viewWidth());
472
setHeight(view()->viewHeight());
475
unsigned cols = frameSet()->totalCols();
476
unsigned rows = frameSet()->totalRows();
478
if (m_rows.m_sizes.size() != rows || m_cols.m_sizes.size() != cols) {
483
LayoutUnit borderThickness = frameSet()->border();
484
layOutAxis(m_rows, frameSet()->rowLengths(), height() - (rows - 1) * borderThickness);
485
layOutAxis(m_cols, frameSet()->colLengths(), width() - (cols - 1) * borderThickness);
487
if (flattenFrameSet())
488
positionFramesWithFlattening();
497
view()->repaintViewRectangle(oldBounds);
498
LayoutRect newBounds = absoluteClippedOverflowRect();
499
if (newBounds != oldBounds)
500
view()->repaintViewRectangle(newBounds);
503
// If this FrameSet has a transform matrix then we need to recompute it
504
// because the transform origin is a function the size of the RenderFrameSet
505
// which may not be computed until it is attached to the render tree.
506
if (layer() && hasTransform())
507
layer()->updateTransform();
509
setNeedsLayout(false);
512
void RenderFrameSet::positionFrames()
514
RenderBox* child = firstChildBox();
518
int rows = frameSet()->totalRows();
519
int cols = frameSet()->totalCols();
522
int borderThickness = frameSet()->border();
523
for (int r = 0; r < rows; r++) {
525
int height = m_rows.m_sizes[r];
526
for (int c = 0; c < cols; c++) {
527
child->setLocation(IntPoint(xPos, yPos));
528
int width = m_cols.m_sizes[c];
530
// has to be resized and itself resize its contents
531
if (width != child->width() || height != child->height()) {
532
child->setWidth(width);
533
child->setHeight(height);
534
child->setNeedsLayout(true);
538
xPos += width + borderThickness;
540
child = child->nextSiblingBox();
544
yPos += height + borderThickness;
547
// all the remaining frames are hidden to avoid ugly spurious unflowed frames
548
for (; child; child = child->nextSiblingBox()) {
551
child->setNeedsLayout(false);
555
void RenderFrameSet::positionFramesWithFlattening()
557
RenderBox* child = firstChildBox();
561
int rows = frameSet()->totalRows();
562
int cols = frameSet()->totalCols();
564
int borderThickness = frameSet()->border();
565
bool repaintNeeded = false;
567
// calculate frameset height based on actual content height to eliminate scrolling
569
for (int r = 0; r < rows && !out; r++) {
571
int height = m_rows.m_sizes[r];
573
for (int c = 0; c < cols; c++) {
574
IntRect oldFrameRect = pixelSnappedIntRect(child->frameRect());
576
int width = m_cols.m_sizes[c];
578
bool fixedWidth = frameSet()->colLengths() && frameSet()->colLengths()[c].isFixed();
579
bool fixedHeight = frameSet()->rowLengths() && frameSet()->rowLengths()[r].isFixed();
581
// has to be resized and itself resize its contents
583
child->setWidth(width ? width + extra / (cols - c) : 0);
585
child->setWidth(width);
586
child->setHeight(height);
588
child->setNeedsLayout(true);
590
if (child->isFrameSet())
591
toRenderFrameSet(child)->layout();
593
toRenderFrame(child)->layoutWithFlattening(fixedWidth, fixedHeight);
595
if (child->height() > m_rows.m_sizes[r])
596
m_rows.m_sizes[r] = child->height();
597
if (child->width() > m_cols.m_sizes[c])
598
m_cols.m_sizes[c] = child->width();
600
if (child->frameRect() != oldFrameRect)
601
repaintNeeded = true;
603
// difference between calculated frame width and the width it actually decides to have
604
extra += width - m_cols.m_sizes[c];
606
child = child->nextSiblingBox();
617
child = firstChildBox();
618
for (int r = 0; r < rows && !out; r++) {
620
for (int c = 0; c < cols; c++) {
621
// ensure the rows and columns are filled
622
IntRect oldRect = pixelSnappedIntRect(child->frameRect());
624
child->setLocation(IntPoint(xPos, yPos));
625
child->setHeight(m_rows.m_sizes[r]);
626
child->setWidth(m_cols.m_sizes[c]);
628
if (child->frameRect() != oldRect) {
629
repaintNeeded = true;
631
// update to final size
632
child->setNeedsLayout(true);
633
if (child->isFrameSet())
634
toRenderFrameSet(child)->layout();
636
toRenderFrame(child)->layoutWithFlattening(true, true);
639
xPos += m_cols.m_sizes[c] + borderThickness;
640
child = child->nextSiblingBox();
646
yPos += m_rows.m_sizes[r] + borderThickness;
649
setWidth(xPos - borderThickness);
650
setHeight(yPos - borderThickness);
655
// all the remaining frames are hidden to avoid ugly spurious unflowed frames
656
for (; child; child = child->nextSiblingBox()) {
659
child->setNeedsLayout(false);
663
bool RenderFrameSet::flattenFrameSet() const
665
return frame() && frame()->settings() && frame()->settings()->frameFlatteningEnabled();
668
void RenderFrameSet::startResizing(GridAxis& axis, int position)
670
int split = hitTestSplit(axis, position);
671
if (split == noSplit || axis.m_preventResize[split]) {
672
axis.m_splitBeingResized = noSplit;
675
axis.m_splitBeingResized = split;
676
axis.m_splitResizeOffset = position - splitPosition(axis, split);
679
void RenderFrameSet::continueResizing(GridAxis& axis, int position)
683
if (axis.m_splitBeingResized == noSplit)
685
int currentSplitPosition = splitPosition(axis, axis.m_splitBeingResized);
686
int delta = (position - currentSplitPosition) - axis.m_splitResizeOffset;
689
axis.m_deltas[axis.m_splitBeingResized - 1] += delta;
690
axis.m_deltas[axis.m_splitBeingResized] -= delta;
691
setNeedsLayout(true);
694
bool RenderFrameSet::userResize(MouseEvent* evt)
696
if (flattenFrameSet())
702
if (evt->type() == eventNames().mousedownEvent && evt->button() == LeftButton) {
703
FloatPoint localPos = absoluteToLocal(evt->absoluteLocation(), UseTransforms | SnapOffsetForTransforms);
704
startResizing(m_cols, localPos.x());
705
startResizing(m_rows, localPos.y());
706
if (m_cols.m_splitBeingResized != noSplit || m_rows.m_splitBeingResized != noSplit) {
712
if (evt->type() == eventNames().mousemoveEvent || (evt->type() == eventNames().mouseupEvent && evt->button() == LeftButton)) {
713
FloatPoint localPos = absoluteToLocal(evt->absoluteLocation(), UseTransforms | SnapOffsetForTransforms);
714
continueResizing(m_cols, localPos.x());
715
continueResizing(m_rows, localPos.y());
716
if (evt->type() == eventNames().mouseupEvent && evt->button() == LeftButton) {
717
setIsResizing(false);
726
void RenderFrameSet::setIsResizing(bool isResizing)
728
m_isResizing = isResizing;
729
for (RenderObject* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
730
if (ancestor->isFrameSet())
731
toRenderFrameSet(ancestor)->m_isChildResizing = isResizing;
733
if (Frame* frame = this->frame())
734
frame->eventHandler()->setResizingFrameSet(isResizing ? frameSet() : 0);
737
bool RenderFrameSet::isResizingRow() const
739
return m_isResizing && m_rows.m_splitBeingResized != noSplit;
742
bool RenderFrameSet::isResizingColumn() const
744
return m_isResizing && m_cols.m_splitBeingResized != noSplit;
747
bool RenderFrameSet::canResizeRow(const IntPoint& p) const
749
int r = hitTestSplit(m_rows, p.y());
750
return r != noSplit && !m_rows.m_preventResize[r];
753
bool RenderFrameSet::canResizeColumn(const IntPoint& p) const
755
int c = hitTestSplit(m_cols, p.x());
756
return c != noSplit && !m_cols.m_preventResize[c];
759
int RenderFrameSet::splitPosition(const GridAxis& axis, int split) const
764
int borderThickness = frameSet()->border();
766
int size = axis.m_sizes.size();
771
for (int i = 0; i < split && i < size; ++i)
772
position += axis.m_sizes[i] + borderThickness;
773
return position - borderThickness;
776
int RenderFrameSet::hitTestSplit(const GridAxis& axis, int position) const
781
int borderThickness = frameSet()->border();
782
if (borderThickness <= 0)
785
size_t size = axis.m_sizes.size();
789
int splitPosition = axis.m_sizes[0];
790
for (size_t i = 1; i < size; ++i) {
791
if (position >= splitPosition && position < splitPosition + borderThickness)
793
splitPosition += borderThickness + axis.m_sizes[i];
798
bool RenderFrameSet::isChildAllowed(RenderObject* child, RenderStyle*) const
800
return child->isFrame() || child->isFrameSet();
803
CursorDirective RenderFrameSet::getCursor(const LayoutPoint& point, Cursor& cursor) const
805
IntPoint roundedPoint = roundedIntPoint(point);
806
if (canResizeRow(roundedPoint)) {
807
cursor = rowResizeCursor();
810
if (canResizeColumn(roundedPoint)) {
811
cursor = columnResizeCursor();
814
return RenderBox::getCursor(point, cursor);
817
} // namespace WebCore