7f816249521f99e38bc0abc49e6ee4ac7d9975ee
[WebKit.git] / Source / WebCore / rendering / RenderView.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "config.h"
22 #include "RenderView.h"
23
24 #include "Document.h"
25 #include "Element.h"
26 #include "FloatQuad.h"
27 #include "Frame.h"
28 #include "FrameView.h"
29 #include "GraphicsContext.h"
30 #include "HTMLFrameOwnerElement.h"
31 #include "HitTestResult.h"
32 #include "RenderLayer.h"
33 #include "RenderSelectionInfo.h"
34 #include "RenderWidget.h"
35 #include "RenderWidgetProtector.h"
36 #include "TransformState.h"
37
38 #if USE(ACCELERATED_COMPOSITING)
39 #include "RenderLayerCompositor.h"
40 #endif
41
42 namespace WebCore {
43
44 RenderView::RenderView(Node* node, FrameView* view)
45     : RenderBlock(node)
46     , m_frameView(view)
47     , m_selectionStart(0)
48     , m_selectionEnd(0)
49     , m_selectionStartPos(-1)
50     , m_selectionEndPos(-1)
51     , m_maximalOutlineSize(0)
52     , m_pageLogicalHeight(0)
53     , m_pageLogicalHeightChanged(false)
54     , m_layoutState(0)
55     , m_layoutStateDisableCount(0)
56 {
57     // Clear our anonymous bit, set because RenderObject assumes
58     // any renderer with document as the node is anonymous.
59     setIsAnonymous(false);
60
61     // init RenderObject attributes
62     setInline(false);
63     
64     m_minPreferredLogicalWidth = 0;
65     m_maxPreferredLogicalWidth = 0;
66
67     setPreferredLogicalWidthsDirty(true, false);
68     
69     setPositioned(true); // to 0,0 :)
70 }
71
72 RenderView::~RenderView()
73 {
74 }
75
76 void RenderView::computeLogicalHeight()
77 {
78     if (!printing() && m_frameView)
79         setLogicalHeight(viewLogicalHeight());
80 }
81
82 void RenderView::computeLogicalWidth()
83 {
84     if (!printing() && m_frameView)
85         setLogicalWidth(viewLogicalWidth());
86 }
87
88 void RenderView::computePreferredLogicalWidths()
89 {
90     ASSERT(preferredLogicalWidthsDirty());
91
92     RenderBlock::computePreferredLogicalWidths();
93
94     m_maxPreferredLogicalWidth = m_minPreferredLogicalWidth;
95 }
96
97 bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const
98 {
99     return child->isBox();
100 }
101
102 void RenderView::layout()
103 {
104     if (!document()->paginated())
105         setPageLogicalHeight(0);
106
107     if (printing())
108         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
109
110     // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
111     bool relayoutChildren = !printing() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
112     if (relayoutChildren) {
113         setChildNeedsLayout(true, false);
114         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
115             if (child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent())
116                 child->setChildNeedsLayout(true, false);
117         }
118     }
119
120     ASSERT(!m_layoutState);
121     LayoutState state;
122     // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
123     state.m_clipped = false;
124     state.m_pageLogicalHeight = m_pageLogicalHeight;
125     state.m_pageLogicalHeightChanged = m_pageLogicalHeightChanged;
126     m_pageLogicalHeightChanged = false;
127     m_layoutState = &state;
128
129     if (needsLayout())
130         RenderBlock::layout();
131
132     ASSERT(layoutDelta() == IntSize());
133     ASSERT(m_layoutStateDisableCount == 0);
134     ASSERT(m_layoutState == &state);
135     m_layoutState = 0;
136     setNeedsLayout(false);
137 }
138
139 void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
140 {
141     // If a container was specified, and was not 0 or the RenderView,
142     // then we should have found it by now.
143     ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
144
145     if (!repaintContainer && useTransforms && shouldUseTransformFromContainer(0)) {
146         TransformationMatrix t;
147         getTransformFromContainer(0, IntSize(), t);
148         transformState.applyTransform(t);
149     }
150     
151     if (fixed && m_frameView)
152         transformState.move(m_frameView->scrollOffsetForFixedPosition());
153 }
154
155 void RenderView::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
156 {
157     if (fixed && m_frameView)
158         transformState.move(-m_frameView->scrollOffsetForFixedPosition());
159
160     if (useTransforms && shouldUseTransformFromContainer(0)) {
161         TransformationMatrix t;
162         getTransformFromContainer(0, IntSize(), t);
163         transformState.applyTransform(t);
164     }
165 }
166
167 void RenderView::paint(PaintInfo& paintInfo, const IntPoint& paintOffset)
168 {
169     // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
170     ASSERT(!needsLayout());
171     paintObject(paintInfo, paintOffset);
172 }
173
174 static inline bool isComposited(RenderObject* object)
175 {
176     return object->hasLayer() && toRenderBoxModelObject(object)->layer()->isComposited();
177 }
178
179 static inline bool rendererObscuresBackground(RenderObject* object)
180 {
181     return object && object->style()->visibility() == VISIBLE
182         && object->style()->opacity() == 1
183         && !object->style()->hasTransform()
184         && !isComposited(object);
185 }
186     
187 void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const IntPoint&)
188 {
189     // Check to see if we are enclosed by a layer that requires complex painting rules.  If so, we cannot blit
190     // when scrolling, and we need to use slow repaints.  Examples of layers that require this are transparent layers,
191     // layers with reflections, or transformed layers.
192     // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being inside
193     // a transform, transparency layer, etc.
194     Element* elt;
195     for (elt = document()->ownerElement(); view() && elt && elt->renderer(); elt = elt->document()->ownerElement()) {
196         RenderLayer* layer = elt->renderer()->enclosingLayer();
197         if (layer->requiresSlowRepaints()) {
198             frameView()->setUseSlowRepaints();
199             break;
200         }
201
202 #if USE(ACCELERATED_COMPOSITING)
203         if (RenderLayer* compositingLayer = layer->enclosingCompositingLayer()) {
204             if (!compositingLayer->backing()->paintingGoesToWindow()) {
205                 frameView()->setUseSlowRepaints();
206                 break;
207             }
208         }
209 #endif
210     }
211
212     if (document()->ownerElement() || !view())
213         return;
214
215     bool rootFillsViewport = false;
216     Node* documentElement = document()->documentElement();
217     if (RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0) {
218         // The document element's renderer is currently forced to be a block, but may not always be.
219         RenderBox* rootBox = rootRenderer->isBox() ? toRenderBox(rootRenderer) : 0;
220         rootFillsViewport = rootBox && !rootBox->x() && !rootBox->y() && rootBox->width() >= width() && rootBox->height() >= height();
221     }
222
223     float pageScaleFactor = 1;
224     if (Frame* frame = m_frameView->frame())
225         pageScaleFactor = frame->pageScaleFactor();
226
227     // If painting will entirely fill the view, no need to fill the background.
228     if (rootFillsViewport && rendererObscuresBackground(firstChild()) && pageScaleFactor >= 1)
229         return;
230
231     // This code typically only executes if the root element's visibility has been set to hidden,
232     // if there is a transform on the <html>, or if there is a page scale factor less than 1.
233     // Only fill with the base background color (typically white) if we're the root document, 
234     // since iframes/frames with no background in the child document should show the parent's background.
235     if (frameView()->isTransparent()) // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being transparent.
236         frameView()->setUseSlowRepaints(); // The parent must show behind the child.
237     else {
238         Color baseColor = frameView()->baseBackgroundColor();
239         if (baseColor.alpha() > 0) {
240             CompositeOperator previousOperator = paintInfo.context->compositeOperation();
241             paintInfo.context->setCompositeOperation(CompositeCopy);
242             paintInfo.context->fillRect(paintInfo.rect, baseColor, style()->colorSpace());
243             paintInfo.context->setCompositeOperation(previousOperator);
244         } else
245             paintInfo.context->clearRect(paintInfo.rect);
246     }
247 }
248
249 bool RenderView::shouldRepaint(const IntRect& r) const
250 {
251     if (printing() || r.width() == 0 || r.height() == 0)
252         return false;
253
254     if (!m_frameView)
255         return false;
256     
257     return true;
258 }
259
260 void RenderView::repaintViewRectangle(const IntRect& ur, bool immediate)
261 {
262     if (!shouldRepaint(ur))
263         return;
264
265     // We always just invalidate the root view, since we could be an iframe that is clipped out
266     // or even invisible.
267     Element* elt = document()->ownerElement();
268     if (!elt)
269         m_frameView->repaintContentRectangle(ur, immediate);
270     else if (RenderBox* obj = elt->renderBox()) {
271         IntRect vr = viewRect();
272         IntRect r = intersection(ur, vr);
273         
274         // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
275         // rectangle.
276         r.moveBy(-vr.location());
277         
278         // FIXME: Hardcoded offsets here are not good.
279         r.move(obj->borderLeft() + obj->paddingLeft(),
280                obj->borderTop() + obj->paddingTop());
281         obj->repaintRectangle(r, immediate);
282     }
283 }
284
285 void RenderView::repaintRectangleInViewAndCompositedLayers(const IntRect& ur, bool immediate)
286 {
287     if (!shouldRepaint(ur))
288         return;
289
290     repaintViewRectangle(ur, immediate);
291     
292 #if USE(ACCELERATED_COMPOSITING)
293     if (compositor()->inCompositingMode())
294         compositor()->repaintCompositedLayersAbsoluteRect(ur);
295 #endif
296 }
297
298 void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
299 {
300     // If a container was specified, and was not 0 or the RenderView,
301     // then we should have found it by now.
302     ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
303
304     if (printing())
305         return;
306
307     if (style()->isFlippedBlocksWritingMode()) {
308         // We have to flip by hand since the view's logical height has not been determined.  We
309         // can use the viewport width and height.
310         if (style()->isHorizontalWritingMode())
311             rect.setY(viewHeight() - rect.maxY());
312         else
313             rect.setX(viewWidth() - rect.maxX());
314     }
315
316     if (fixed && m_frameView)
317         rect.move(m_frameView->scrollXForFixedPosition(), m_frameView->scrollYForFixedPosition());
318         
319     // Apply our transform if we have one (because of full page zooming).
320     if (!repaintContainer && m_layer && m_layer->transform())
321         rect = m_layer->transform()->mapRect(rect);
322 }
323
324 void RenderView::absoluteRects(Vector<IntRect>& rects, const IntPoint& accumulatedOffset)
325 {
326     rects.append(IntRect(accumulatedOffset, m_layer->size()));
327 }
328
329 void RenderView::absoluteQuads(Vector<FloatQuad>& quads)
330 {
331     quads.append(FloatRect(FloatPoint(), m_layer->size()));
332 }
333
334 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)
335 {
336     if (!object)
337         return 0;
338
339     RenderObject* child = object->childAt(offset);
340     return child ? child : object->nextInPreOrderAfterChildren();
341 }
342
343 IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
344 {
345     document()->updateStyleIfNeeded();
346
347     typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectionMap;
348     SelectionMap selectedObjects;
349
350     RenderObject* os = m_selectionStart;
351     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
352     while (os && os != stop) {
353         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
354             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
355             selectedObjects.set(os, new RenderSelectionInfo(os, clipToVisibleContent));
356             RenderBlock* cb = os->containingBlock();
357             while (cb && !cb->isRenderView()) {
358                 RenderSelectionInfo* blockInfo = selectedObjects.get(cb);
359                 if (blockInfo)
360                     break;
361                 selectedObjects.set(cb, new RenderSelectionInfo(cb, clipToVisibleContent));
362                 cb = cb->containingBlock();
363             }
364         }
365
366         os = os->nextInPreOrder();
367     }
368
369     // Now create a single bounding box rect that encloses the whole selection.
370     IntRect selRect;
371     SelectionMap::iterator end = selectedObjects.end();
372     for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
373         RenderSelectionInfo* info = i->second;
374         // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
375         IntRect currRect = info->rect();
376         if (RenderBoxModelObject* repaintContainer = info->repaintContainer()) {
377             FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
378             currRect = absQuad.enclosingBoundingBox(); 
379         }
380         selRect.unite(currRect);
381         delete info;
382     }
383     return selRect;
384 }
385
386 #if USE(ACCELERATED_COMPOSITING)
387 // Compositing layer dimensions take outline size into account, so we have to recompute layer
388 // bounds when it changes.
389 // FIXME: This is ugly; it would be nice to have a better way to do this.
390 void RenderView::setMaximalOutlineSize(int o)
391 {
392     if (o != m_maximalOutlineSize) {
393         m_maximalOutlineSize = o;
394
395         // maximalOutlineSize affects compositing layer dimensions.
396         compositor()->setCompositingLayersNeedRebuild();    // FIXME: this really just needs to be a geometry update.
397     }
398 }
399 #endif
400
401 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
402 {
403     // Make sure both our start and end objects are defined.
404     // Check www.msnbc.com and try clicking around to find the case where this happened.
405     if ((start && !end) || (end && !start))
406         return;
407
408     // Just return if the selection hasn't changed.
409     if (m_selectionStart == start && m_selectionStartPos == startPos &&
410         m_selectionEnd == end && m_selectionEndPos == endPos)
411         return;
412
413     // Record the old selected objects.  These will be used later
414     // when we compare against the new selected objects.
415     int oldStartPos = m_selectionStartPos;
416     int oldEndPos = m_selectionEndPos;
417
418     // Objects each have a single selection rect to examine.
419     typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectedObjectMap;
420     SelectedObjectMap oldSelectedObjects;
421     SelectedObjectMap newSelectedObjects;
422
423     // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
424     // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
425     // the union of those rects might remain the same even when changes have occurred.
426     typedef HashMap<RenderBlock*, RenderBlockSelectionInfo*> SelectedBlockMap;
427     SelectedBlockMap oldSelectedBlocks;
428     SelectedBlockMap newSelectedBlocks;
429
430     RenderObject* os = m_selectionStart;
431     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
432     while (os && os != stop) {
433         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
434             // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
435             oldSelectedObjects.set(os, new RenderSelectionInfo(os, true));
436             if (blockRepaintMode == RepaintNewXOROld) {
437                 RenderBlock* cb = os->containingBlock();
438                 while (cb && !cb->isRenderView()) {
439                     RenderBlockSelectionInfo* blockInfo = oldSelectedBlocks.get(cb);
440                     if (blockInfo)
441                         break;
442                     oldSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
443                     cb = cb->containingBlock();
444                 }
445             }
446         }
447
448         os = os->nextInPreOrder();
449     }
450
451     // Now clear the selection.
452     SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
453     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i)
454         i->first->setSelectionState(SelectionNone);
455
456     // set selection start and end
457     m_selectionStart = start;
458     m_selectionStartPos = startPos;
459     m_selectionEnd = end;
460     m_selectionEndPos = endPos;
461
462     // Update the selection status of all objects between m_selectionStart and m_selectionEnd
463     if (start && start == end)
464         start->setSelectionState(SelectionBoth);
465     else {
466         if (start)
467             start->setSelectionState(SelectionStart);
468         if (end)
469             end->setSelectionState(SelectionEnd);
470     }
471
472     RenderObject* o = start;
473     stop = rendererAfterPosition(end, endPos);
474
475     while (o && o != stop) {
476         if (o != start && o != end && o->canBeSelectionLeaf())
477             o->setSelectionState(SelectionInside);
478         o = o->nextInPreOrder();
479     }
480
481     m_layer->clearBlockSelectionGapsBounds();
482
483     // Now that the selection state has been updated for the new objects, walk them again and
484     // put them in the new objects list.
485     o = start;
486     while (o && o != stop) {
487         if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
488             newSelectedObjects.set(o, new RenderSelectionInfo(o, true));
489             RenderBlock* cb = o->containingBlock();
490             while (cb && !cb->isRenderView()) {
491                 RenderBlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
492                 if (blockInfo)
493                     break;
494                 newSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
495                 cb = cb->containingBlock();
496             }
497         }
498
499         o = o->nextInPreOrder();
500     }
501
502     if (!m_frameView) {
503         // We built the maps, but we aren't going to use them.
504         // We need to delete the values, otherwise they'll all leak!
505         deleteAllValues(oldSelectedObjects);
506         deleteAllValues(newSelectedObjects);
507         deleteAllValues(oldSelectedBlocks);
508         deleteAllValues(newSelectedBlocks);
509         return;
510     }
511
512     m_frameView->beginDeferredRepaints();
513
514     // Have any of the old selected objects changed compared to the new selection?
515     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
516         RenderObject* obj = i->first;
517         RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
518         RenderSelectionInfo* oldInfo = i->second;
519         if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state() ||
520             (m_selectionStart == obj && oldStartPos != m_selectionStartPos) ||
521             (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
522             oldInfo->repaint();
523             if (newInfo) {
524                 newInfo->repaint();
525                 newSelectedObjects.remove(obj);
526                 delete newInfo;
527             }
528         }
529         delete oldInfo;
530     }
531
532     // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
533     SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
534     for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i) {
535         RenderSelectionInfo* newInfo = i->second;
536         newInfo->repaint();
537         delete newInfo;
538     }
539
540     // Have any of the old blocks changed?
541     SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
542     for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
543         RenderBlock* block = i->first;
544         RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
545         RenderBlockSelectionInfo* oldInfo = i->second;
546         if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
547             oldInfo->repaint();
548             if (newInfo) {
549                 newInfo->repaint();
550                 newSelectedBlocks.remove(block);
551                 delete newInfo;
552             }
553         }
554         delete oldInfo;
555     }
556
557     // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
558     SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
559     for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i) {
560         RenderBlockSelectionInfo* newInfo = i->second;
561         newInfo->repaint();
562         delete newInfo;
563     }
564
565     m_frameView->endDeferredRepaints();
566 }
567
568 void RenderView::clearSelection()
569 {
570     m_layer->repaintBlockSelectionGaps();
571     setSelection(0, -1, 0, -1, RepaintNewMinusOld);
572 }
573
574 void RenderView::selectionStartEnd(int& startPos, int& endPos) const
575 {
576     startPos = m_selectionStartPos;
577     endPos = m_selectionEndPos;
578 }
579
580 bool RenderView::printing() const
581 {
582     return document()->printing();
583 }
584
585 size_t RenderView::getRetainedWidgets(Vector<RenderWidget*>& renderWidgets)
586 {
587     size_t size = m_widgets.size();
588
589     renderWidgets.reserveCapacity(size);
590
591     RenderWidgetSet::const_iterator end = m_widgets.end();
592     for (RenderWidgetSet::const_iterator it = m_widgets.begin(); it != end; ++it) {
593         renderWidgets.uncheckedAppend(*it);
594         (*it)->ref();
595     }
596     
597     return size;
598 }
599
600 void RenderView::releaseWidgets(Vector<RenderWidget*>& renderWidgets)
601 {
602     size_t size = renderWidgets.size();
603
604     for (size_t i = 0; i < size; ++i)
605         renderWidgets[i]->deref(renderArena());
606 }
607
608 void RenderView::updateWidgetPositions()
609 {
610     // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
611     // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
612     // alive during enumeration.    
613
614     Vector<RenderWidget*> renderWidgets;
615     size_t size = getRetainedWidgets(renderWidgets);
616     
617     for (size_t i = 0; i < size; ++i)
618         renderWidgets[i]->updateWidgetPosition();
619
620     for (size_t i = 0; i < size; ++i)
621         renderWidgets[i]->widgetPositionsUpdated();
622
623     releaseWidgets(renderWidgets);
624 }
625
626 void RenderView::addWidget(RenderWidget* o)
627 {
628     m_widgets.add(o);
629 }
630
631 void RenderView::removeWidget(RenderWidget* o)
632 {
633     m_widgets.remove(o);
634 }
635
636 void RenderView::notifyWidgets(WidgetNotification notification)
637 {
638     Vector<RenderWidget*> renderWidgets;
639     size_t size = getRetainedWidgets(renderWidgets);
640
641     for (size_t i = 0; i < size; ++i)
642         renderWidgets[i]->notifyWidget(notification);
643
644     releaseWidgets(renderWidgets);
645 }
646
647 IntRect RenderView::viewRect() const
648 {
649     if (printing())
650         return IntRect(0, 0, width(), height());
651     if (m_frameView)
652         return m_frameView->visibleContentRect();
653     return IntRect();
654 }
655
656 IntRect RenderView::documentRect() const
657 {
658     IntRect overflowRect(layoutOverflowRect());
659     flipForWritingMode(overflowRect);
660     if (hasTransform())
661         overflowRect = layer()->currentTransform().mapRect(overflowRect);
662     return overflowRect;
663 }
664
665 int RenderView::viewHeight() const
666 {
667     int height = 0;
668     if (!printing() && m_frameView) {
669         height = m_frameView->layoutHeight();
670         height = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(height)) : height;
671     }
672     return height;
673 }
674
675 int RenderView::viewWidth() const
676 {
677     int width = 0;
678     if (!printing() && m_frameView) {
679         width = m_frameView->layoutWidth();
680         width = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(width)) : width;
681     }
682     return width;
683 }
684
685 float RenderView::zoomFactor() const
686 {
687     Frame* frame = m_frameView->frame();
688     return frame ? frame->pageZoomFactor() : 1;
689 }
690
691 void RenderView::pushLayoutState(RenderObject* root)
692 {
693     ASSERT(m_layoutStateDisableCount == 0);
694     ASSERT(m_layoutState == 0);
695
696     m_layoutState = new (renderArena()) LayoutState(root);
697 }
698
699 bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
700 {
701     RenderObject* o = renderer;
702     while (o) {
703         if (o->hasColumns() || o->hasTransform() || o->hasReflection())
704             return true;
705         o = o->container();
706     }
707     return false;
708 }
709
710 void RenderView::updateHitTestResult(HitTestResult& result, const IntPoint& point)
711 {
712     if (result.innerNode())
713         return;
714
715     Node* node = document()->documentElement();
716     if (node) {
717         result.setInnerNode(node);
718         if (!result.innerNonSharedNode())
719             result.setInnerNonSharedNode(node);
720         result.setLocalPoint(point);
721     }
722 }
723
724 // FIXME: This function is obsolete and only used by embedded WebViews inside AppKit NSViews.
725 // Do not add callers of this function!
726 // The idea here is to take into account what object is moving the pagination point, and
727 // thus choose the best place to chop it.
728 void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
729 {
730     // Nobody else can set a page break once we have a forced break.
731     if (m_legacyPrinting.m_forcedPageBreak)
732         return;
733
734     // Forced breaks always win over unforced breaks.
735     if (forcedBreak) {
736         m_legacyPrinting.m_forcedPageBreak = true;
737         m_legacyPrinting.m_bestTruncatedAt = y;
738         return;
739     }
740
741     // Prefer the widest object that tries to move the pagination point
742     IntRect boundingBox = forRenderer->borderBoundingBox();
743     if (boundingBox.width() > m_legacyPrinting.m_truncatorWidth) {
744         m_legacyPrinting.m_truncatorWidth = boundingBox.width();
745         m_legacyPrinting.m_bestTruncatedAt = y;
746     }
747 }
748
749 #if USE(ACCELERATED_COMPOSITING)
750 bool RenderView::usesCompositing() const
751 {
752     return m_compositor && m_compositor->inCompositingMode();
753 }
754
755 RenderLayerCompositor* RenderView::compositor()
756 {
757     if (!m_compositor)
758         m_compositor = adoptPtr(new RenderLayerCompositor(this));
759
760     return m_compositor.get();
761 }
762 #endif
763
764 void RenderView::didMoveOnscreen()
765 {
766 #if USE(ACCELERATED_COMPOSITING)
767     if (m_compositor)
768         m_compositor->didMoveOnscreen();
769 #endif
770 }
771
772 void RenderView::willMoveOffscreen()
773 {
774 #if USE(ACCELERATED_COMPOSITING)
775     if (m_compositor)
776         m_compositor->willMoveOffscreen();
777 #endif
778 }
779
780 } // namespace WebCore