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