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