highlight for Ruby text is mispositioned in the Web Inspector
[WebKit-https.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 "ColumnInfo.h"
25 #include "Document.h"
26 #include "Element.h"
27 #include "FloatQuad.h"
28 #include "FlowThreadController.h"
29 #include "Frame.h"
30 #include "FrameView.h"
31 #include "GraphicsContext.h"
32 #include "HTMLFrameOwnerElement.h"
33 #include "HitTestResult.h"
34 #include "Page.h"
35 #include "RenderLayer.h"
36 #include "RenderNamedFlowThread.h"
37 #include "RenderSelectionInfo.h"
38 #include "RenderWidget.h"
39 #include "RenderWidgetProtector.h"
40 #include "TransformState.h"
41
42 #if USE(ACCELERATED_COMPOSITING)
43 #include "RenderLayerCompositor.h"
44 #endif
45
46 namespace WebCore {
47
48 RenderView::RenderView(Node* node, FrameView* view)
49     : RenderBlock(node)
50     , m_frameView(view)
51     , m_selectionStart(0)
52     , m_selectionEnd(0)
53     , m_selectionStartPos(-1)
54     , m_selectionEndPos(-1)
55     , m_maximalOutlineSize(0)
56     , m_pageLogicalHeight(0)
57     , m_pageLogicalHeightChanged(false)
58     , m_layoutState(0)
59     , m_layoutStateDisableCount(0)
60 {
61     // Clear our anonymous bit, set because RenderObject assumes
62     // any renderer with document as the node is anonymous.
63     setIsAnonymous(false);
64
65     // init RenderObject attributes
66     setInline(false);
67     
68     m_minPreferredLogicalWidth = 0;
69     m_maxPreferredLogicalWidth = 0;
70
71     setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
72     
73     setPositioned(true); // to 0,0 :)
74 }
75
76 RenderView::~RenderView()
77 {
78 }
79
80 bool RenderView::hitTest(const HitTestRequest& request, HitTestResult& result)
81 {
82     return layer()->hitTest(request, result);
83 }
84
85 void RenderView::computeLogicalHeight()
86 {
87     if (!printing() && m_frameView)
88         setLogicalHeight(viewLogicalHeight());
89 }
90
91 void RenderView::computeLogicalWidth()
92 {
93     if (!printing() && m_frameView)
94         setLogicalWidth(viewLogicalWidth());
95 }
96
97 void RenderView::computePreferredLogicalWidths()
98 {
99     ASSERT(preferredLogicalWidthsDirty());
100
101     RenderBlock::computePreferredLogicalWidths();
102 }
103
104 bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const
105 {
106     return child->isBox();
107 }
108
109 void RenderView::layout()
110 {
111     if (!document()->paginated())
112         setPageLogicalHeight(0);
113
114     if (printing())
115         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
116
117     // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
118     bool relayoutChildren = !printing() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
119     if (relayoutChildren) {
120         setChildNeedsLayout(true, MarkOnlyThis);
121         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
122             if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight())
123                     || child->style()->logicalHeight().isPercent()
124                     || child->style()->logicalMinHeight().isPercent()
125                     || child->style()->logicalMaxHeight().isPercent())
126                 child->setChildNeedsLayout(true, MarkOnlyThis);
127         }
128     }
129
130     ASSERT(!m_layoutState);
131     LayoutState state;
132     // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
133     state.m_clipped = false;
134     state.m_pageLogicalHeight = m_pageLogicalHeight;
135     state.m_pageLogicalHeightChanged = m_pageLogicalHeightChanged;
136     state.m_isPaginated = state.m_pageLogicalHeight;
137     m_pageLogicalHeightChanged = false;
138     m_layoutState = &state;
139
140     if (needsLayout()) {
141         RenderBlock::layout();
142         if (hasRenderNamedFlowThreads())
143             flowThreadController()->layoutRenderNamedFlowThreads();
144     }
145
146     ASSERT(layoutDelta() == LayoutSize());
147     ASSERT(m_layoutStateDisableCount == 0);
148     ASSERT(m_layoutState == &state);
149     m_layoutState = 0;
150     setNeedsLayout(false);
151 }
152
153 void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState, ApplyContainerFlipOrNot, bool* wasFixed) const
154 {
155     // If a container was specified, and was not 0 or the RenderView,
156     // then we should have found it by now.
157     ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
158     ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == fixed);
159
160     if (!repaintContainer && useTransforms && shouldUseTransformFromContainer(0)) {
161         TransformationMatrix t;
162         getTransformFromContainer(0, LayoutSize(), t);
163         transformState.applyTransform(t);
164     }
165     
166     if (fixed && m_frameView)
167         transformState.move(m_frameView->scrollOffsetForFixedPosition());
168 }
169
170 void RenderView::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
171 {
172     if (fixed && m_frameView)
173         transformState.move(m_frameView->scrollOffsetForFixedPosition());
174
175     if (useTransforms && shouldUseTransformFromContainer(0)) {
176         TransformationMatrix t;
177         getTransformFromContainer(0, LayoutSize(), t);
178         transformState.applyTransform(t);
179     }
180 }
181
182 bool RenderView::requiresColumns(int desiredColumnCount) const
183 {
184     if (m_frameView) {
185         if (Frame* frame = m_frameView->frame()) {
186             if (Page* page = frame->page())
187                 return frame == page->mainFrame() && page->pagination().mode != Page::Pagination::Unpaginated;
188         }
189     }
190     return RenderBlock::requiresColumns(desiredColumnCount);
191 }
192
193 void RenderView::calcColumnWidth()
194 {
195     int columnWidth = contentLogicalWidth();
196     if (m_frameView && style()->hasInlineColumnAxis()) {
197         if (Frame* frame = m_frameView->frame()) {
198             if (Page* page = frame->page()) {
199                 if (int pageLength = page->pagination().pageLength)
200                     columnWidth = pageLength;
201             }
202         }
203     }
204     setDesiredColumnCountAndWidth(1, columnWidth);
205 }
206
207 ColumnInfo::PaginationUnit RenderView::paginationUnit() const
208 {
209     if (m_frameView) {
210         if (Frame* frame = m_frameView->frame()) {
211             if (Page* page = frame->page())
212                 return (frame == page->mainFrame() && page->pagination().behavesLikeColumns) ? ColumnInfo::Column : ColumnInfo::Page;
213         }
214     }
215     return ColumnInfo::Page;
216 }
217
218 void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
219 {
220     // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
221     ASSERT(!needsLayout());
222     // RenderViews should never be called to paint with an offset not on device pixels.
223     ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffset);
224     paintObject(paintInfo, paintOffset);
225 }
226
227 static inline bool isComposited(RenderObject* object)
228 {
229     return object->hasLayer() && toRenderBoxModelObject(object)->layer()->isComposited();
230 }
231
232 static inline bool rendererObscuresBackground(RenderObject* object)
233 {
234     return object && object->style()->visibility() == VISIBLE
235         && object->style()->opacity() == 1
236         && !object->style()->hasTransform()
237         && !isComposited(object);
238 }
239     
240 void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
241 {
242     // Check to see if we are enclosed by a layer that requires complex painting rules.  If so, we cannot blit
243     // when scrolling, and we need to use slow repaints.  Examples of layers that require this are transparent layers,
244     // layers with reflections, or transformed layers.
245     // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being inside
246     // a transform, transparency layer, etc.
247     Element* elt;
248     for (elt = document()->ownerElement(); view() && elt && elt->renderer(); elt = elt->document()->ownerElement()) {
249         RenderLayer* layer = elt->renderer()->enclosingLayer();
250         if (layer->cannotBlitToWindow()) {
251             frameView()->setCannotBlitToWindow();
252             break;
253         }
254
255 #if USE(ACCELERATED_COMPOSITING)
256         if (RenderLayer* compositingLayer = layer->enclosingCompositingLayerForRepaint()) {
257             if (!compositingLayer->backing()->paintsIntoWindow()) {
258                 frameView()->setCannotBlitToWindow();
259                 break;
260             }
261         }
262 #endif
263     }
264
265     if (document()->ownerElement() || !view())
266         return;
267
268     bool rootFillsViewport = false;
269     Node* documentElement = document()->documentElement();
270     if (RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0) {
271         // The document element's renderer is currently forced to be a block, but may not always be.
272         RenderBox* rootBox = rootRenderer->isBox() ? toRenderBox(rootRenderer) : 0;
273         rootFillsViewport = rootBox && !rootBox->x() && !rootBox->y() && rootBox->width() >= width() && rootBox->height() >= height();
274     }
275     
276     Page* page = document()->page();
277     float pageScaleFactor = page ? page->pageScaleFactor() : 1;
278
279     // If painting will entirely fill the view, no need to fill the background.
280     if (rootFillsViewport && rendererObscuresBackground(firstChild()) && pageScaleFactor >= 1)
281         return;
282
283     // This code typically only executes if the root element's visibility has been set to hidden,
284     // if there is a transform on the <html>, or if there is a page scale factor less than 1.
285     // Only fill with the base background color (typically white) if we're the root document, 
286     // since iframes/frames with no background in the child document should show the parent's background.
287     if (frameView()->isTransparent()) // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being transparent.
288         frameView()->setCannotBlitToWindow(); // The parent must show behind the child.
289     else {
290         Color baseColor = frameView()->baseBackgroundColor();
291         if (baseColor.alpha() > 0) {
292             CompositeOperator previousOperator = paintInfo.context->compositeOperation();
293             paintInfo.context->setCompositeOperation(CompositeCopy);
294             paintInfo.context->fillRect(paintInfo.rect, baseColor, style()->colorSpace());
295             paintInfo.context->setCompositeOperation(previousOperator);
296         } else
297             paintInfo.context->clearRect(paintInfo.rect);
298     }
299 }
300
301 bool RenderView::shouldRepaint(const LayoutRect& r) const
302 {
303     if (printing() || r.width() == 0 || r.height() == 0)
304         return false;
305
306     if (!m_frameView)
307         return false;
308
309     if (m_frameView->repaintsDisabled())
310         return false;
311
312     return true;
313 }
314
315 void RenderView::repaintViewRectangle(const LayoutRect& ur, bool immediate)
316 {
317     if (!shouldRepaint(ur))
318         return;
319
320     // We always just invalidate the root view, since we could be an iframe that is clipped out
321     // or even invisible.
322     Element* elt = document()->ownerElement();
323     if (!elt)
324         m_frameView->repaintContentRectangle(pixelSnappedIntRect(ur), immediate);
325     else if (RenderBox* obj = elt->renderBox()) {
326         LayoutRect vr = viewRect();
327         LayoutRect r = intersection(ur, vr);
328         
329         // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
330         // rectangle.
331         r.moveBy(-vr.location());
332
333         // FIXME: Hardcoded offsets here are not good.
334         r.moveBy(obj->contentBoxRect().location());
335         obj->repaintRectangle(r, immediate);
336     }
337 }
338
339 void RenderView::repaintRectangleInViewAndCompositedLayers(const LayoutRect& ur, bool immediate)
340 {
341     if (!shouldRepaint(ur))
342         return;
343
344     repaintViewRectangle(ur, immediate);
345     
346 #if USE(ACCELERATED_COMPOSITING)
347     if (compositor()->inCompositingMode())
348         compositor()->repaintCompositedLayersAbsoluteRect(pixelSnappedIntRect(ur));
349 #endif
350 }
351
352 void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
353 {
354     // If a container was specified, and was not 0 or the RenderView,
355     // then we should have found it by now.
356     ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
357
358     if (printing())
359         return;
360
361     if (style()->isFlippedBlocksWritingMode()) {
362         // We have to flip by hand since the view's logical height has not been determined.  We
363         // can use the viewport width and height.
364         if (style()->isHorizontalWritingMode())
365             rect.setY(viewHeight() - rect.maxY());
366         else
367             rect.setX(viewWidth() - rect.maxX());
368     }
369
370     if (fixed && m_frameView)
371         rect.move(m_frameView->scrollXForFixedPosition(), m_frameView->scrollYForFixedPosition());
372         
373     // Apply our transform if we have one (because of full page zooming).
374     if (!repaintContainer && m_layer && m_layer->transform())
375         rect = m_layer->transform()->mapRect(rect);
376 }
377
378 void RenderView::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
379 {
380     rects.append(pixelSnappedIntRect(accumulatedOffset, m_layer->size()));
381 }
382
383 void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
384 {
385     if (wasFixed)
386         *wasFixed = false;
387     quads.append(FloatRect(FloatPoint(), m_layer->size()));
388 }
389
390 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)
391 {
392     if (!object)
393         return 0;
394
395     RenderObject* child = object->childAt(offset);
396     return child ? child : object->nextInPreOrderAfterChildren();
397 }
398
399 IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
400 {
401     document()->updateStyleIfNeeded();
402
403     typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectionMap;
404     SelectionMap selectedObjects;
405
406     RenderObject* os = m_selectionStart;
407     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
408     while (os && os != stop) {
409         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
410             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
411             selectedObjects.set(os, new RenderSelectionInfo(os, clipToVisibleContent));
412             RenderBlock* cb = os->containingBlock();
413             while (cb && !cb->isRenderView()) {
414                 RenderSelectionInfo* blockInfo = selectedObjects.get(cb);
415                 if (blockInfo)
416                     break;
417                 selectedObjects.set(cb, new RenderSelectionInfo(cb, clipToVisibleContent));
418                 cb = cb->containingBlock();
419             }
420         }
421
422         os = os->nextInPreOrder();
423     }
424
425     // Now create a single bounding box rect that encloses the whole selection.
426     LayoutRect selRect;
427     SelectionMap::iterator end = selectedObjects.end();
428     for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
429         RenderSelectionInfo* info = i->second;
430         // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
431         LayoutRect currRect = info->rect();
432         if (RenderBoxModelObject* repaintContainer = info->repaintContainer()) {
433             FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
434             currRect = absQuad.enclosingBoundingBox(); 
435         }
436         selRect.unite(currRect);
437         delete info;
438     }
439     return pixelSnappedIntRect(selRect);
440 }
441
442 #if USE(ACCELERATED_COMPOSITING)
443 // Compositing layer dimensions take outline size into account, so we have to recompute layer
444 // bounds when it changes.
445 // FIXME: This is ugly; it would be nice to have a better way to do this.
446 void RenderView::setMaximalOutlineSize(int o)
447 {
448     if (o != m_maximalOutlineSize) {
449         m_maximalOutlineSize = o;
450
451         // maximalOutlineSize affects compositing layer dimensions.
452         compositor()->setCompositingLayersNeedRebuild();    // FIXME: this really just needs to be a geometry update.
453     }
454 }
455 #endif
456
457 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
458 {
459     // Make sure both our start and end objects are defined.
460     // Check www.msnbc.com and try clicking around to find the case where this happened.
461     if ((start && !end) || (end && !start))
462         return;
463
464     // Just return if the selection hasn't changed.
465     if (m_selectionStart == start && m_selectionStartPos == startPos &&
466         m_selectionEnd == end && m_selectionEndPos == endPos)
467         return;
468
469     // Record the old selected objects.  These will be used later
470     // when we compare against the new selected objects.
471     int oldStartPos = m_selectionStartPos;
472     int oldEndPos = m_selectionEndPos;
473
474     // Objects each have a single selection rect to examine.
475     typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectedObjectMap;
476     SelectedObjectMap oldSelectedObjects;
477     SelectedObjectMap newSelectedObjects;
478
479     // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
480     // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
481     // the union of those rects might remain the same even when changes have occurred.
482     typedef HashMap<RenderBlock*, RenderBlockSelectionInfo*> SelectedBlockMap;
483     SelectedBlockMap oldSelectedBlocks;
484     SelectedBlockMap newSelectedBlocks;
485
486     RenderObject* os = m_selectionStart;
487     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
488     while (os && os != stop) {
489         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
490             // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
491             oldSelectedObjects.set(os, new RenderSelectionInfo(os, true));
492             if (blockRepaintMode == RepaintNewXOROld) {
493                 RenderBlock* cb = os->containingBlock();
494                 while (cb && !cb->isRenderView()) {
495                     RenderBlockSelectionInfo* blockInfo = oldSelectedBlocks.get(cb);
496                     if (blockInfo)
497                         break;
498                     oldSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
499                     cb = cb->containingBlock();
500                 }
501             }
502         }
503
504         os = os->nextInPreOrder();
505     }
506
507     // Now clear the selection.
508     SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
509     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i)
510         i->first->setSelectionStateIfNeeded(SelectionNone);
511
512     // set selection start and end
513     m_selectionStart = start;
514     m_selectionStartPos = startPos;
515     m_selectionEnd = end;
516     m_selectionEndPos = endPos;
517
518     // Update the selection status of all objects between m_selectionStart and m_selectionEnd
519     if (start && start == end)
520         start->setSelectionStateIfNeeded(SelectionBoth);
521     else {
522         if (start)
523             start->setSelectionStateIfNeeded(SelectionStart);
524         if (end)
525             end->setSelectionStateIfNeeded(SelectionEnd);
526     }
527
528     RenderObject* o = start;
529     stop = rendererAfterPosition(end, endPos);
530
531     while (o && o != stop) {
532         if (o != start && o != end && o->canBeSelectionLeaf())
533             o->setSelectionStateIfNeeded(SelectionInside);
534         o = o->nextInPreOrder();
535     }
536
537     if (blockRepaintMode != RepaintNothing)
538         m_layer->clearBlockSelectionGapsBounds();
539
540     // Now that the selection state has been updated for the new objects, walk them again and
541     // put them in the new objects list.
542     o = start;
543     while (o && o != stop) {
544         if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
545             newSelectedObjects.set(o, new RenderSelectionInfo(o, true));
546             RenderBlock* cb = o->containingBlock();
547             while (cb && !cb->isRenderView()) {
548                 RenderBlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
549                 if (blockInfo)
550                     break;
551                 newSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
552                 cb = cb->containingBlock();
553             }
554         }
555
556         o = o->nextInPreOrder();
557     }
558
559     if (!m_frameView || blockRepaintMode == RepaintNothing) {
560         // We built the maps, but we aren't going to use them.
561         // We need to delete the values, otherwise they'll all leak!
562         deleteAllValues(oldSelectedObjects);
563         deleteAllValues(newSelectedObjects);
564         deleteAllValues(oldSelectedBlocks);
565         deleteAllValues(newSelectedBlocks);
566         return;
567     }
568
569     m_frameView->beginDeferredRepaints();
570
571     // Have any of the old selected objects changed compared to the new selection?
572     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
573         RenderObject* obj = i->first;
574         RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
575         RenderSelectionInfo* oldInfo = i->second;
576         if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state() ||
577             (m_selectionStart == obj && oldStartPos != m_selectionStartPos) ||
578             (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
579             oldInfo->repaint();
580             if (newInfo) {
581                 newInfo->repaint();
582                 newSelectedObjects.remove(obj);
583                 delete newInfo;
584             }
585         }
586         delete oldInfo;
587     }
588
589     // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
590     SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
591     for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i) {
592         RenderSelectionInfo* newInfo = i->second;
593         newInfo->repaint();
594         delete newInfo;
595     }
596
597     // Have any of the old blocks changed?
598     SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
599     for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
600         RenderBlock* block = i->first;
601         RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
602         RenderBlockSelectionInfo* oldInfo = i->second;
603         if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
604             oldInfo->repaint();
605             if (newInfo) {
606                 newInfo->repaint();
607                 newSelectedBlocks.remove(block);
608                 delete newInfo;
609             }
610         }
611         delete oldInfo;
612     }
613
614     // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
615     SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
616     for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i) {
617         RenderBlockSelectionInfo* newInfo = i->second;
618         newInfo->repaint();
619         delete newInfo;
620     }
621
622     m_frameView->endDeferredRepaints();
623 }
624
625 void RenderView::getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const
626 {
627     startRenderer = m_selectionStart;
628     startOffset = m_selectionStartPos;
629     endRenderer = m_selectionEnd;
630     endOffset = m_selectionEndPos;
631 }
632
633 void RenderView::clearSelection()
634 {
635     m_layer->repaintBlockSelectionGaps();
636     setSelection(0, -1, 0, -1, RepaintNewMinusOld);
637 }
638
639 void RenderView::selectionStartEnd(int& startPos, int& endPos) const
640 {
641     startPos = m_selectionStartPos;
642     endPos = m_selectionEndPos;
643 }
644
645 bool RenderView::printing() const
646 {
647     return document()->printing();
648 }
649
650 size_t RenderView::getRetainedWidgets(Vector<RenderWidget*>& renderWidgets)
651 {
652     size_t size = m_widgets.size();
653
654     renderWidgets.reserveCapacity(size);
655
656     RenderWidgetSet::const_iterator end = m_widgets.end();
657     for (RenderWidgetSet::const_iterator it = m_widgets.begin(); it != end; ++it) {
658         renderWidgets.uncheckedAppend(*it);
659         (*it)->ref();
660     }
661     
662     return size;
663 }
664
665 void RenderView::releaseWidgets(Vector<RenderWidget*>& renderWidgets)
666 {
667     size_t size = renderWidgets.size();
668
669     for (size_t i = 0; i < size; ++i)
670         renderWidgets[i]->deref(renderArena());
671 }
672
673 void RenderView::updateWidgetPositions()
674 {
675     // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
676     // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
677     // alive during enumeration.    
678
679     Vector<RenderWidget*> renderWidgets;
680     size_t size = getRetainedWidgets(renderWidgets);
681     
682     for (size_t i = 0; i < size; ++i)
683         renderWidgets[i]->updateWidgetPosition();
684
685     for (size_t i = 0; i < size; ++i)
686         renderWidgets[i]->widgetPositionsUpdated();
687
688     releaseWidgets(renderWidgets);
689 }
690
691 void RenderView::addWidget(RenderWidget* o)
692 {
693     m_widgets.add(o);
694 }
695
696 void RenderView::removeWidget(RenderWidget* o)
697 {
698     m_widgets.remove(o);
699 }
700
701 void RenderView::notifyWidgets(WidgetNotification notification)
702 {
703     Vector<RenderWidget*> renderWidgets;
704     size_t size = getRetainedWidgets(renderWidgets);
705
706     for (size_t i = 0; i < size; ++i)
707         renderWidgets[i]->notifyWidget(notification);
708
709     releaseWidgets(renderWidgets);
710 }
711
712 LayoutRect RenderView::viewRect() const
713 {
714     if (printing())
715         return LayoutRect(LayoutPoint(), size());
716     if (m_frameView)
717         return m_frameView->visibleContentRect();
718     return LayoutRect();
719 }
720
721
722 IntRect RenderView::unscaledDocumentRect() const
723 {
724     LayoutRect overflowRect(layoutOverflowRect());
725     flipForWritingMode(overflowRect);
726     return pixelSnappedIntRect(overflowRect);
727 }
728
729 LayoutRect RenderView::backgroundRect(RenderBox* backgroundRenderer) const
730 {
731     if (!hasColumns())
732         return unscaledDocumentRect();
733
734     ColumnInfo* columnInfo = this->columnInfo();
735     LayoutRect backgroundRect(0, 0, columnInfo->desiredColumnWidth(), columnInfo->columnHeight() * columnInfo->columnCount());
736     if (!isHorizontalWritingMode())
737         backgroundRect = backgroundRect.transposedRect();
738     backgroundRenderer->flipForWritingMode(backgroundRect);
739
740     return backgroundRect;
741 }
742
743 IntRect RenderView::documentRect() const
744 {
745     IntRect overflowRect(unscaledDocumentRect());
746     if (hasTransform())
747         overflowRect = layer()->currentTransform().mapRect(overflowRect);
748     return overflowRect;
749 }
750
751 int RenderView::viewHeight() const
752 {
753     int height = 0;
754     if (!printing() && m_frameView) {
755         height = m_frameView->layoutHeight();
756         height = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(height)) : height;
757     }
758     return height;
759 }
760
761 int RenderView::viewWidth() const
762 {
763     int width = 0;
764     if (!printing() && m_frameView) {
765         width = m_frameView->layoutWidth();
766         width = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(width)) : width;
767     }
768     return width;
769 }
770
771 int RenderView::viewLogicalHeight() const
772 {
773     int height = style()->isHorizontalWritingMode() ? viewHeight() : viewWidth();
774
775     if (hasColumns() && !style()->hasInlineColumnAxis()) {
776         if (Frame* frame = m_frameView->frame()) {
777             if (Page* page = frame->page()) {
778                 if (frame == page->mainFrame()) {
779                     if (int pageLength = page->pagination().pageLength)
780                         height = pageLength;
781                 }
782             }
783         }
784     }
785
786     return height;
787 }
788
789 float RenderView::zoomFactor() const
790 {
791     Frame* frame = m_frameView->frame();
792     return frame ? frame->pageZoomFactor() : 1;
793 }
794
795 void RenderView::pushLayoutState(RenderObject* root)
796 {
797     ASSERT(m_layoutStateDisableCount == 0);
798     ASSERT(m_layoutState == 0);
799
800     m_layoutState = new (renderArena()) LayoutState(root);
801 }
802
803 void RenderView::pushLayoutState(RenderFlowThread* flowThread, bool regionsChanged)
804 {
805     m_layoutState = new (renderArena()) LayoutState(m_layoutState, flowThread, regionsChanged);
806 }
807
808 bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
809 {
810     RenderObject* o = renderer;
811     while (o) {
812         if (o->hasColumns() || o->hasTransform() || o->hasReflection())
813             return true;
814         o = o->container();
815     }
816     return false;
817 }
818
819 void RenderView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
820 {
821     if (result.innerNode())
822         return;
823
824     Node* node = document()->documentElement();
825     if (node) {
826         result.setInnerNode(node);
827         if (!result.innerNonSharedNode())
828             result.setInnerNonSharedNode(node);
829         result.setLocalPoint(point);
830     }
831 }
832
833 // FIXME: This function is obsolete and only used by embedded WebViews inside AppKit NSViews.
834 // Do not add callers of this function!
835 // The idea here is to take into account what object is moving the pagination point, and
836 // thus choose the best place to chop it.
837 void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
838 {
839     // Nobody else can set a page break once we have a forced break.
840     if (m_legacyPrinting.m_forcedPageBreak)
841         return;
842
843     // Forced breaks always win over unforced breaks.
844     if (forcedBreak) {
845         m_legacyPrinting.m_forcedPageBreak = true;
846         m_legacyPrinting.m_bestTruncatedAt = y;
847         return;
848     }
849
850     // Prefer the widest object that tries to move the pagination point
851     IntRect boundingBox = forRenderer->borderBoundingBox();
852     if (boundingBox.width() > m_legacyPrinting.m_truncatorWidth) {
853         m_legacyPrinting.m_truncatorWidth = boundingBox.width();
854         m_legacyPrinting.m_bestTruncatedAt = y;
855     }
856 }
857
858 #if USE(ACCELERATED_COMPOSITING)
859 bool RenderView::usesCompositing() const
860 {
861     return m_compositor && m_compositor->inCompositingMode();
862 }
863
864 RenderLayerCompositor* RenderView::compositor()
865 {
866     if (!m_compositor)
867         m_compositor = adoptPtr(new RenderLayerCompositor(this));
868
869     return m_compositor.get();
870 }
871 #endif
872
873 void RenderView::didMoveOnscreen()
874 {
875 #if USE(ACCELERATED_COMPOSITING)
876     if (m_compositor)
877         m_compositor->didMoveOnscreen();
878 #endif
879 }
880
881 void RenderView::willMoveOffscreen()
882 {
883 #if USE(ACCELERATED_COMPOSITING)
884     if (m_compositor)
885         m_compositor->willMoveOffscreen();
886 #endif
887 }
888
889 void RenderView::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
890 {
891     RenderBlock::styleDidChange(diff, oldStyle);
892     
893     for (RenderObject* renderer = firstChild(); renderer; renderer = renderer->nextSibling()) {
894         if (renderer->isRenderNamedFlowThread()) {
895             RenderNamedFlowThread* flowRenderer = toRenderNamedFlowThread(renderer);
896             flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(style()));
897         }
898     }
899 }
900
901 bool RenderView::hasRenderNamedFlowThreads() const
902 {
903     return m_flowThreadController && m_flowThreadController->hasRenderNamedFlowThreads();
904 }
905
906 FlowThreadController* RenderView::flowThreadController()
907 {
908     if (!m_flowThreadController)
909         m_flowThreadController = FlowThreadController::create(this);
910
911     return m_flowThreadController.get();
912 }
913
914 RenderBlock::IntervalArena* RenderView::intervalArena()
915 {
916     if (!m_intervalArena)
917         m_intervalArena = IntervalArena::create();
918     return m_intervalArena.get();
919 }
920
921 void RenderView::setFixedPositionedObjectsNeedLayout()
922 {
923     ASSERT(m_frameView);
924
925     PositionedObjectsListHashSet* positionedObjects = this->positionedObjects();
926     if (!positionedObjects)
927         return;
928
929     PositionedObjectsListHashSet::const_iterator end = positionedObjects->end();
930     for (PositionedObjectsListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) {
931         RenderBox* currBox = *it;
932         currBox->setNeedsLayout(true);
933     }
934 }
935
936 void RenderView::insertFixedPositionedObject(RenderBox* object)
937 {
938     if (!m_positionedObjects)
939         m_positionedObjects = adoptPtr(new PositionedObjectsListHashSet);
940
941     m_positionedObjects->add(object);
942 }
943
944 void RenderView::removeFixedPositionedObject(RenderBox* object)
945 {
946     if (!m_positionedObjects)
947         return;
948
949     m_positionedObjects->remove(object);
950 }
951
952 } // namespace WebCore