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