Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / 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 "core/rendering/RenderView.h"
23
24 #include "core/dom/Document.h"
25 #include "core/dom/Element.h"
26 #include "core/frame/LocalFrame.h"
27 #include "core/html/HTMLFrameOwnerElement.h"
28 #include "core/html/HTMLIFrameElement.h"
29 #include "core/page/Page.h"
30 #include "core/paint/ViewPainter.h"
31 #include "core/rendering/ColumnInfo.h"
32 #include "core/rendering/FlowThreadController.h"
33 #include "core/rendering/GraphicsContextAnnotator.h"
34 #include "core/rendering/HitTestResult.h"
35 #include "core/rendering/RenderFlowThread.h"
36 #include "core/rendering/RenderGeometryMap.h"
37 #include "core/rendering/RenderLayer.h"
38 #include "core/rendering/RenderPart.h"
39 #include "core/rendering/RenderQuote.h"
40 #include "core/rendering/RenderSelectionInfo.h"
41 #include "core/rendering/compositing/CompositedLayerMapping.h"
42 #include "core/rendering/compositing/RenderLayerCompositor.h"
43 #include "core/svg/SVGDocumentExtensions.h"
44 #include "platform/TraceEvent.h"
45 #include "platform/geometry/FloatQuad.h"
46 #include "platform/geometry/TransformState.h"
47 #include "platform/graphics/GraphicsContext.h"
48
49 namespace blink {
50
51 RenderView::RenderView(Document* document)
52     : RenderBlockFlow(document)
53     , m_frameView(document->view())
54     , m_selectionStart(nullptr)
55     , m_selectionEnd(nullptr)
56     , m_selectionStartPos(-1)
57     , m_selectionEndPos(-1)
58     , m_pageLogicalHeight(0)
59     , m_pageLogicalHeightChanged(false)
60     , m_layoutState(0)
61     , m_renderQuoteHead(nullptr)
62     , m_renderCounterCount(0)
63     , m_hitTestCount(0)
64 {
65     // init RenderObject attributes
66     setInline(false);
67
68     m_minPreferredLogicalWidth = 0;
69     m_maxPreferredLogicalWidth = 0;
70
71     setPreferredLogicalWidthsDirty(MarkOnlyThis);
72
73     setPositionState(AbsolutePosition); // to 0,0 :)
74 }
75
76 RenderView::~RenderView()
77 {
78 }
79
80 void RenderView::trace(Visitor* visitor)
81 {
82     visitor->trace(m_selectionStart);
83     visitor->trace(m_selectionEnd);
84     visitor->trace(m_renderQuoteHead);
85     RenderBlockFlow::trace(visitor);
86 }
87
88 bool RenderView::hitTest(const HitTestRequest& request, HitTestResult& result)
89 {
90     return hitTest(request, result.hitTestLocation(), result);
91 }
92
93 bool RenderView::hitTest(const HitTestRequest& request, const HitTestLocation& location, HitTestResult& result)
94 {
95     TRACE_EVENT0("blink", "RenderView::hitTest");
96     m_hitTestCount++;
97
98     // We have to recursively update layout/style here because otherwise, when the hit test recurses
99     // into a child document, it could trigger a layout on the parent document, which can destroy RenderLayers
100     // that are higher up in the call stack, leading to crashes.
101     // Note that Document::updateLayout calls its parent's updateLayout.
102     // FIXME: It should be the caller's responsibility to ensure an up-to-date layout.
103     frameView()->updateLayoutAndStyleIfNeededRecursive();
104
105     bool hitLayer = layer()->hitTest(request, location, result);
106
107     // FrameView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls,
108     // so we need to test FrameView scrollbars separately here. Note that it's important we do this after
109     // the hit test above, because that may overwrite the entire HitTestResult when it finds a hit.
110     IntPoint viewPoint = location.roundedPoint() - frameView()->scrollOffset();
111     if (Scrollbar* frameScrollbar = frameView()->scrollbarAtViewPoint(viewPoint))
112         result.setScrollbar(frameScrollbar);
113
114     return hitLayer;
115 }
116
117 void RenderView::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit, LogicalExtentComputedValues& computedValues) const
118 {
119     computedValues.m_extent = (!shouldUsePrintingLayout() && m_frameView) ? LayoutUnit(viewLogicalHeight()) : logicalHeight;
120 }
121
122 void RenderView::updateLogicalWidth()
123 {
124     if (!shouldUsePrintingLayout() && m_frameView)
125         setLogicalWidth(viewLogicalWidth());
126 }
127
128 LayoutUnit RenderView::availableLogicalHeight(AvailableLogicalHeightType heightType) const
129 {
130     // If we have columns, then the available logical height is reduced to the column height.
131     if (hasColumns())
132         return columnInfo()->columnHeight();
133     return RenderBlockFlow::availableLogicalHeight(heightType);
134 }
135
136 bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const
137 {
138     return child->isBox();
139 }
140
141 void RenderView::layoutContent()
142 {
143     ASSERT(needsLayout());
144
145     RenderBlockFlow::layout();
146
147 #if ENABLE(ASSERT)
148     checkLayoutState();
149 #endif
150 }
151
152 #if ENABLE(ASSERT)
153 void RenderView::checkLayoutState()
154 {
155     ASSERT(!m_layoutState->next());
156 }
157 #endif
158
159 bool RenderView::shouldDoFullPaintInvalidationForNextLayout() const
160 {
161     // It's hard to predict here which of full paint invalidation or per-descendant paint invalidation costs less.
162     // For vertical writing mode or width change it's more likely that per-descendant paint invalidation
163     // eventually turns out to be full paint invalidation but with the cost to handle more layout states
164     // and discrete paint invalidation rects, so marking full paint invalidation here is more likely to cost less.
165     // Otherwise, per-descendant paint invalidation is more likely to avoid unnecessary full paint invalidation.
166
167     if (shouldUsePrintingLayout())
168         return true;
169
170     if (!style()->isHorizontalWritingMode() || width() != viewWidth())
171         return true;
172
173     if (height() != viewHeight()) {
174         if (RenderObject* backgroundRenderer = this->backgroundRenderer()) {
175             // When background-attachment is 'fixed', we treat the viewport (instead of the 'root'
176             // i.e. html or body) as the background positioning area, and we should full paint invalidation
177             // viewport resize if the background image is not composited and needs full paint invalidation on
178             // background positioning area resize.
179             if (!m_compositor || !m_compositor->needsFixedRootBackgroundLayer(layer())) {
180                 if (backgroundRenderer->style()->hasFixedBackgroundImage()
181                     && mustInvalidateFillLayersPaintOnHeightChange(backgroundRenderer->style()->backgroundLayers()))
182                     return true;
183             }
184         }
185     }
186
187     return false;
188 }
189
190 void RenderView::layout()
191 {
192     if (!document().paginated())
193         setPageLogicalHeight(0);
194
195     if (shouldUsePrintingLayout())
196         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
197
198     SubtreeLayoutScope layoutScope(*this);
199
200     // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
201     bool relayoutChildren = !shouldUsePrintingLayout() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
202     if (relayoutChildren) {
203         layoutScope.setChildNeedsLayout(this);
204         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
205             if (child->isSVGRoot())
206                 continue;
207
208             if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight())
209                     || child->style()->logicalHeight().isPercent()
210                     || child->style()->logicalMinHeight().isPercent()
211                     || child->style()->logicalMaxHeight().isPercent())
212                 layoutScope.setChildNeedsLayout(child);
213         }
214
215         if (document().svgExtensions())
216             document().accessSVGExtensions().invalidateSVGRootsWithRelativeLengthDescendents(&layoutScope);
217     }
218
219     ASSERT(!m_layoutState);
220     if (!needsLayout())
221         return;
222
223     LayoutState rootLayoutState(pageLogicalHeight(), pageLogicalHeightChanged(), *this);
224
225     m_pageLogicalHeightChanged = false;
226
227     layoutContent();
228
229 #if ENABLE(ASSERT)
230     checkLayoutState();
231 #endif
232     clearNeedsLayout();
233 }
234
235 void RenderView::mapLocalToContainer(const RenderLayerModelObject* paintInvalidationContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed, const PaintInvalidationState* paintInvalidationState) const
236 {
237     ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == static_cast<bool>(mode & IsFixed));
238
239     if (!paintInvalidationContainer && mode & UseTransforms && shouldUseTransformFromContainer(0)) {
240         TransformationMatrix t;
241         getTransformFromContainer(0, LayoutSize(), t);
242         transformState.applyTransform(t);
243     }
244
245     if ((mode & IsFixed) && m_frameView) {
246         transformState.move(m_frameView->scrollOffsetForFixedPosition());
247         // IsFixed flag is only applicable within this RenderView.
248         mode &= ~IsFixed;
249     }
250
251     if (paintInvalidationContainer == this)
252         return;
253
254     if (mode & TraverseDocumentBoundaries) {
255         if (RenderObject* parentDocRenderer = frame()->ownerRenderer()) {
256             transformState.move(-frame()->view()->scrollOffset());
257             if (parentDocRenderer->isBox())
258                 transformState.move(toLayoutSize(toRenderBox(parentDocRenderer)->contentBoxRect().location()));
259             parentDocRenderer->mapLocalToContainer(paintInvalidationContainer, transformState, mode, wasFixed, paintInvalidationState);
260             return;
261         }
262     }
263 }
264
265 const RenderObject* RenderView::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
266 {
267     LayoutSize offsetForFixedPosition;
268     LayoutSize offset;
269     RenderObject* container = 0;
270
271     if (m_frameView)
272         offsetForFixedPosition = m_frameView->scrollOffsetForFixedPosition();
273
274     if (geometryMap.mapCoordinatesFlags() & TraverseDocumentBoundaries) {
275         if (RenderPart* parentDocRenderer = frame()->ownerRenderer()) {
276             offset = -m_frameView->scrollOffset();
277             offset += toLayoutSize(parentDocRenderer->contentBoxRect().location());
278             container = parentDocRenderer;
279         }
280     }
281
282     // If a container was specified, and was not 0 or the RenderView, then we
283     // should have found it by now unless we're traversing to a parent document.
284     ASSERT_ARG(ancestorToStopAt, !ancestorToStopAt || ancestorToStopAt == this || container);
285
286     if ((!ancestorToStopAt || container) && shouldUseTransformFromContainer(container)) {
287         TransformationMatrix t;
288         getTransformFromContainer(container, LayoutSize(), t);
289         geometryMap.push(this, t, false, false, false, true, offsetForFixedPosition);
290     } else {
291         geometryMap.push(this, offset, false, false, false, false, offsetForFixedPosition);
292     }
293
294     return container;
295 }
296
297 void RenderView::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
298 {
299     if (mode & IsFixed && m_frameView)
300         transformState.move(m_frameView->scrollOffsetForFixedPosition());
301
302     if (mode & UseTransforms && shouldUseTransformFromContainer(0)) {
303         TransformationMatrix t;
304         getTransformFromContainer(0, LayoutSize(), t);
305         transformState.applyTransform(t);
306     }
307 }
308
309 void RenderView::computeSelfHitTestRects(Vector<LayoutRect>& rects, const LayoutPoint&) const
310 {
311     // Record the entire size of the contents of the frame. Note that we don't just
312     // use the viewport size (containing block) here because we want to ensure this includes
313     // all children (so we can avoid walking them explicitly).
314     rects.append(LayoutRect(LayoutPoint::zero(), frameView()->contentsSize()));
315 }
316
317 void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
318 {
319     ViewPainter(*this).paint(paintInfo, paintOffset);
320 }
321
322 void RenderView::paintBoxDecorationBackground(PaintInfo& paintInfo, const LayoutPoint&)
323 {
324     ViewPainter(*this).paintBoxDecorationBackground(paintInfo);
325 }
326
327 void RenderView::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState)
328 {
329     ASSERT(!needsLayout());
330
331     // We specifically need to issue paint invalidations for the viewRect since other renderers
332     // short-circuit on full-paint invalidation.
333     LayoutRect dirtyRect = viewRect();
334     if (doingFullPaintInvalidation() && !dirtyRect.isEmpty()) {
335         const RenderLayerModelObject* paintInvalidationContainer = &paintInvalidationState.paintInvalidationContainer();
336         mapRectToPaintInvalidationBacking(paintInvalidationContainer, dirtyRect, &paintInvalidationState);
337         invalidatePaintUsingContainer(paintInvalidationContainer, dirtyRect, PaintInvalidationFull);
338     }
339     RenderBlock::invalidateTreeIfNeeded(paintInvalidationState);
340 }
341
342 void RenderView::invalidatePaintForRectangle(const LayoutRect& paintInvalidationRect, PaintInvalidationReason invalidationReason) const
343 {
344     ASSERT(!paintInvalidationRect.isEmpty());
345
346     if (document().printing() || !m_frameView)
347         return;
348
349     ASSERT(layer()->compositingState() == PaintsIntoOwnBacking || !frame()->ownerRenderer());
350
351     if (layer()->compositingState() == PaintsIntoOwnBacking) {
352         setBackingNeedsPaintInvalidationInRect(paintInvalidationRect, invalidationReason);
353     } else {
354         m_frameView->contentRectangleForPaintInvalidation(pixelSnappedIntRect(paintInvalidationRect));
355     }
356 }
357
358 void RenderView::invalidatePaintForViewAndCompositedLayers()
359 {
360     setShouldDoFullPaintInvalidation();
361
362     // The only way we know how to hit these ASSERTS below this point is via the Chromium OS login screen.
363     DisableCompositingQueryAsserts disabler;
364
365     if (compositor()->inCompositingMode())
366         compositor()->fullyInvalidatePaint();
367 }
368
369 void RenderView::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState* invalidationState) const
370 {
371     mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, IsNotFixedPosition, invalidationState);
372 }
373
374 void RenderView::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, ViewportConstrainedPosition viewportConstraint, const PaintInvalidationState* state) const
375 {
376     if (document().printing())
377         return;
378
379     if (style()->slowIsFlippedBlocksWritingMode()) {
380         // We have to flip by hand since the view's logical height has not been determined.  We
381         // can use the viewport width and height.
382         if (style()->isHorizontalWritingMode())
383             rect.setY(viewHeight() - rect.maxY());
384         else
385             rect.setX(viewWidth() - rect.maxX());
386     }
387
388     adjustViewportConstrainedOffset(rect, viewportConstraint);
389
390     // Apply our transform if we have one (because of full page zooming).
391     if (!paintInvalidationContainer && layer() && layer()->transform())
392         rect = layer()->transform()->mapRect(rect);
393
394     ASSERT(paintInvalidationContainer);
395     if (paintInvalidationContainer == this)
396         return;
397
398     Element* owner = document().ownerElement();
399     if (!owner)
400         return;
401
402     if (RenderBox* obj = owner->renderBox()) {
403         // Intersect the viewport with the paint invalidation rect.
404         LayoutRect viewRectangle = viewRect();
405         rect.intersect(viewRectangle);
406
407         // Adjust for scroll offset of the view.
408         rect.moveBy(-viewRectangle.location());
409
410         // Adjust for frame border.
411         rect.moveBy(obj->contentBoxRect().location());
412         obj->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, 0);
413     }
414 }
415
416 void RenderView::adjustViewportConstrainedOffset(LayoutRect& rect, ViewportConstrainedPosition viewportConstraint) const
417 {
418     if (viewportConstraint != IsFixedPosition)
419         return;
420
421     if (m_frameView) {
422         rect.move(m_frameView->scrollOffsetForFixedPosition());
423         // If we have a pending scroll, invalidate the previous scroll position.
424         if (!m_frameView->pendingScrollDelta().isZero())
425             rect.move(-LayoutSize(m_frameView->pendingScrollDelta()));
426     }
427 }
428
429 void RenderView::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
430 {
431     rects.append(pixelSnappedIntRect(accumulatedOffset, layer()->size()));
432 }
433
434 void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
435 {
436     if (wasFixed)
437         *wasFixed = false;
438     quads.append(FloatRect(FloatPoint(), layer()->size()));
439 }
440
441 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)
442 {
443     if (!object)
444         return 0;
445
446     RenderObject* child = object->childAt(offset);
447     return child ? child : object->nextInPreOrderAfterChildren();
448 }
449
450 IntRect RenderView::selectionBounds() const
451 {
452     typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, OwnPtrWillBeMember<RenderSelectionInfo> > SelectionMap;
453     SelectionMap selectedObjects;
454
455     RenderObject* os = m_selectionStart;
456     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
457     while (os && os != stop) {
458         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
459             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
460             selectedObjects.set(os, adoptPtrWillBeNoop(new RenderSelectionInfo(os)));
461             RenderBlock* cb = os->containingBlock();
462             while (cb && !cb->isRenderView()) {
463                 OwnPtrWillBeMember<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).storedValue->value;
464                 if (blockInfo)
465                     break;
466                 blockInfo = adoptPtrWillBeNoop(new RenderSelectionInfo(cb));
467                 cb = cb->containingBlock();
468             }
469         }
470
471         os = os->nextInPreOrder();
472     }
473
474     // Now create a single bounding box rect that encloses the whole selection.
475     LayoutRect selRect;
476     SelectionMap::iterator end = selectedObjects.end();
477     for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i)
478         selRect.unite(i->value->absoluteSelectionRect());
479
480     return pixelSnappedIntRect(selRect);
481 }
482
483 void RenderView::invalidatePaintForSelection() const
484 {
485     HashSet<RenderBlock*> processedBlocks;
486
487     RenderObject* end = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
488     for (RenderObject* o = m_selectionStart; o && o != end; o = o->nextInPreOrder()) {
489         if (!o->canBeSelectionLeaf() && o != m_selectionStart && o != m_selectionEnd)
490             continue;
491         if (o->selectionState() == SelectionNone)
492             continue;
493
494         o->setShouldInvalidateSelection();
495
496         // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
497         for (RenderBlock* block = o->containingBlock(); block && !block->isRenderView(); block = block->containingBlock()) {
498             if (!processedBlocks.add(block).isNewEntry)
499                 break;
500             block->setShouldInvalidateSelection();
501         }
502     }
503 }
504
505 // When exploring the RenderTree looking for the nodes involved in the Selection, sometimes it's
506 // required to change the traversing direction because the "start" position is below the "end" one.
507 static inline RenderObject* getNextOrPrevRenderObjectBasedOnDirection(const RenderObject* o, const RenderObject* stop, bool& continueExploring, bool& exploringBackwards)
508 {
509     RenderObject* next;
510     if (exploringBackwards) {
511         next = o->previousInPreOrder();
512         continueExploring = next && !(next)->isRenderView();
513     } else {
514         next = o->nextInPreOrder();
515         continueExploring = next && next != stop;
516         exploringBackwards = !next && (next != stop);
517         if (exploringBackwards) {
518             next = stop->previousInPreOrder();
519             continueExploring = next && !next->isRenderView();
520         }
521     }
522
523     return next;
524 }
525
526 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode)
527 {
528     // This code makes no assumptions as to if the rendering tree is up to date or not
529     // and will not try to update it. Currently clearSelection calls this
530     // (intentionally) without updating the rendering tree as it doesn't care.
531     // Other callers may want to force recalc style before calling this.
532
533     // Make sure both our start and end objects are defined.
534     // Check www.msnbc.com and try clicking around to find the case where this happened.
535     if ((start && !end) || (end && !start))
536         return;
537
538     // Just return if the selection hasn't changed.
539     if (m_selectionStart == start && m_selectionStartPos == startPos &&
540         m_selectionEnd == end && m_selectionEndPos == endPos)
541         return;
542
543     // Record the old selected objects.  These will be used later
544     // when we compare against the new selected objects.
545     int oldStartPos = m_selectionStartPos;
546     int oldEndPos = m_selectionEndPos;
547
548     // Objects each have a single selection rect to examine.
549     typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, SelectionState > SelectedObjectMap;
550     SelectedObjectMap oldSelectedObjects;
551     // FIXME: |newSelectedObjects| doesn't really need to store the SelectionState, it's just more convenient
552     // to have it use the same data structure as |oldSelectedObjects|.
553     SelectedObjectMap newSelectedObjects;
554
555     // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
556     // In order to get the paint invalidation rect right, we have to examine left, middle, and right rects individually, since otherwise
557     // the union of those rects might remain the same even when changes have occurred.
558     typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, SelectionState > SelectedBlockMap;
559     SelectedBlockMap oldSelectedBlocks;
560     // FIXME: |newSelectedBlocks| doesn't really need to store the SelectionState, it's just more convenient
561     // to have it use the same data structure as |oldSelectedBlocks|.
562     SelectedBlockMap newSelectedBlocks;
563
564     RenderObject* os = m_selectionStart;
565     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
566     bool exploringBackwards = false;
567     bool continueExploring = os && (os != stop);
568     while (continueExploring) {
569         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
570             // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
571             oldSelectedObjects.set(os, os->selectionState());
572             if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) {
573                 RenderBlock* cb = os->containingBlock();
574                 while (cb && !cb->isRenderView()) {
575                     SelectedBlockMap::AddResult result = oldSelectedBlocks.add(cb, cb->selectionState());
576                     if (!result.isNewEntry)
577                         break;
578                     cb = cb->containingBlock();
579                 }
580             }
581         }
582
583         os = getNextOrPrevRenderObjectBasedOnDirection(os, stop, continueExploring, exploringBackwards);
584     }
585
586     // Now clear the selection.
587     SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
588     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i)
589         i->key->setSelectionStateIfNeeded(SelectionNone);
590
591     // set selection start and end
592     m_selectionStart = start;
593     m_selectionStartPos = startPos;
594     m_selectionEnd = end;
595     m_selectionEndPos = endPos;
596
597     // Update the selection status of all objects between m_selectionStart and m_selectionEnd
598     if (start && start == end)
599         start->setSelectionStateIfNeeded(SelectionBoth);
600     else {
601         if (start)
602             start->setSelectionStateIfNeeded(SelectionStart);
603         if (end)
604             end->setSelectionStateIfNeeded(SelectionEnd);
605     }
606
607     RenderObject* o = start;
608     stop = rendererAfterPosition(end, endPos);
609
610     while (o && o != stop) {
611         if (o != start && o != end && o->canBeSelectionLeaf())
612             o->setSelectionStateIfNeeded(SelectionInside);
613         o = o->nextInPreOrder();
614     }
615
616     layer()->clearBlockSelectionGapsBounds();
617
618     // Now that the selection state has been updated for the new objects, walk them again and
619     // put them in the new objects list.
620     o = start;
621     exploringBackwards = false;
622     continueExploring = o && (o != stop);
623     while (continueExploring) {
624         if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
625             newSelectedObjects.set(o, o->selectionState());
626             RenderBlock* cb = o->containingBlock();
627             while (cb && !cb->isRenderView()) {
628                 SelectedBlockMap::AddResult result = newSelectedBlocks.add(cb, cb->selectionState());
629                 if (!result.isNewEntry)
630                     break;
631                 cb = cb->containingBlock();
632             }
633         }
634
635         o = getNextOrPrevRenderObjectBasedOnDirection(o, stop, continueExploring, exploringBackwards);
636     }
637
638     if (!m_frameView)
639         return;
640
641     // Have any of the old selected objects changed compared to the new selection?
642     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
643         RenderObject* obj = i->key;
644         SelectionState newSelectionState = obj->selectionState();
645         SelectionState oldSelectionState = i->value;
646         if (newSelectionState != oldSelectionState
647             || (m_selectionStart == obj && oldStartPos != m_selectionStartPos)
648             || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
649             obj->setShouldInvalidateSelection();
650             newSelectedObjects.remove(obj);
651         }
652     }
653
654     // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
655     SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
656     for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i)
657         i->key->setShouldInvalidateSelection();
658
659     // Have any of the old blocks changed?
660     SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
661     for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
662         RenderBlock* block = i->key;
663         SelectionState newSelectionState = block->selectionState();
664         SelectionState oldSelectionState = i->value;
665         if (newSelectionState != oldSelectionState) {
666             block->setShouldInvalidateSelection();
667             newSelectedBlocks.remove(block);
668         }
669     }
670
671     // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
672     SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
673     for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i)
674         i->key->setShouldInvalidateSelection();
675 }
676
677 void RenderView::clearSelection()
678 {
679     // For querying RenderLayer::compositingState()
680     // This is correct, since destroying render objects needs to cause eager paint invalidations.
681     DisableCompositingQueryAsserts disabler;
682
683     layer()->invalidatePaintForBlockSelectionGaps();
684     setSelection(0, -1, 0, -1, PaintInvalidationNewMinusOld);
685 }
686
687 void RenderView::selectionStartEnd(int& startPos, int& endPos) const
688 {
689     startPos = m_selectionStartPos;
690     endPos = m_selectionEndPos;
691 }
692
693 bool RenderView::shouldUsePrintingLayout() const
694 {
695     if (!document().printing() || !m_frameView)
696         return false;
697     return m_frameView->frame().shouldUsePrintingLayout();
698 }
699
700 LayoutRect RenderView::viewRect() const
701 {
702     if (shouldUsePrintingLayout())
703         return LayoutRect(LayoutPoint(), size());
704     if (m_frameView)
705         return m_frameView->visibleContentRect();
706     return LayoutRect();
707 }
708
709 IntRect RenderView::unscaledDocumentRect() const
710 {
711     LayoutRect overflowRect(layoutOverflowRect());
712     flipForWritingMode(overflowRect);
713     return pixelSnappedIntRect(overflowRect);
714 }
715
716 bool RenderView::rootBackgroundIsEntirelyFixed() const
717 {
718     if (RenderObject* backgroundRenderer = this->backgroundRenderer())
719         return backgroundRenderer->hasEntirelyFixedBackground();
720     return false;
721 }
722
723 RenderObject* RenderView::backgroundRenderer() const
724 {
725     if (Element* documentElement = document().documentElement()) {
726         if (RenderObject* rootObject = documentElement->renderer())
727             return rootObject->rendererForRootBackground();
728     }
729     return 0;
730 }
731
732 LayoutRect RenderView::backgroundRect(RenderBox* backgroundRenderer) const
733 {
734     if (!hasColumns())
735         return unscaledDocumentRect();
736
737     ColumnInfo* columnInfo = this->columnInfo();
738     LayoutRect backgroundRect(0, 0, columnInfo->desiredColumnWidth(), columnInfo->columnHeight() * columnInfo->columnCount());
739     if (!isHorizontalWritingMode())
740         backgroundRect = backgroundRect.transposedRect();
741     backgroundRenderer->flipForWritingMode(backgroundRect);
742
743     return backgroundRect;
744 }
745
746 IntRect RenderView::documentRect() const
747 {
748     FloatRect overflowRect(unscaledDocumentRect());
749     if (hasTransformRelatedProperty())
750         overflowRect = layer()->currentTransform().mapRect(overflowRect);
751     return IntRect(overflowRect);
752 }
753
754 int RenderView::viewHeight(IncludeScrollbarsInRect scrollbarInclusion) const
755 {
756     int height = 0;
757     if (!shouldUsePrintingLayout() && m_frameView)
758         height = m_frameView->layoutSize(scrollbarInclusion).height();
759
760     return height;
761 }
762
763 int RenderView::viewWidth(IncludeScrollbarsInRect scrollbarInclusion) const
764 {
765     int width = 0;
766     if (!shouldUsePrintingLayout() && m_frameView)
767         width = m_frameView->layoutSize(scrollbarInclusion).width();
768
769     return width;
770 }
771
772 int RenderView::viewLogicalHeight() const
773 {
774     return style()->isHorizontalWritingMode() ? viewHeight(ExcludeScrollbars) : viewWidth(ExcludeScrollbars);
775 }
776
777 LayoutUnit RenderView::viewLogicalHeightForPercentages() const
778 {
779     if (shouldUsePrintingLayout())
780         return pageLogicalHeight();
781     return viewLogicalHeight();
782 }
783
784 float RenderView::zoomFactor() const
785 {
786     return m_frameView->frame().pageZoomFactor();
787 }
788
789 void RenderView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
790 {
791     if (result.innerNode())
792         return;
793
794     Node* node = document().documentElement();
795     if (node) {
796         result.setInnerNode(node);
797         if (!result.innerNonSharedNode())
798             result.setInnerNonSharedNode(node);
799
800         LayoutPoint adjustedPoint = point;
801         offsetForContents(adjustedPoint);
802
803         result.setLocalPoint(adjustedPoint);
804     }
805 }
806
807 bool RenderView::usesCompositing() const
808 {
809     return m_compositor && m_compositor->staleInCompositingMode();
810 }
811
812 RenderLayerCompositor* RenderView::compositor()
813 {
814     if (!m_compositor)
815         m_compositor = adoptPtr(new RenderLayerCompositor(*this));
816
817     return m_compositor.get();
818 }
819
820 void RenderView::setIsInWindow(bool isInWindow)
821 {
822     if (m_compositor)
823         m_compositor->setIsInWindow(isInWindow);
824 }
825
826 FlowThreadController* RenderView::flowThreadController()
827 {
828     if (!m_flowThreadController)
829         m_flowThreadController = FlowThreadController::create();
830
831     return m_flowThreadController.get();
832 }
833
834 void RenderView::pushLayoutState(LayoutState& layoutState)
835 {
836     if (m_flowThreadController) {
837         RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();
838         if (currentFlowThread)
839             currentFlowThread->pushFlowThreadLayoutState(layoutState.renderer());
840     }
841     m_layoutState = &layoutState;
842 }
843
844 void RenderView::popLayoutState()
845 {
846     ASSERT(m_layoutState);
847     m_layoutState = m_layoutState->next();
848     if (!m_flowThreadController)
849         return;
850
851     RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();
852     if (!currentFlowThread)
853         return;
854
855     currentFlowThread->popFlowThreadLayoutState();
856 }
857
858 IntervalArena* RenderView::intervalArena()
859 {
860     if (!m_intervalArena)
861         m_intervalArena = IntervalArena::create();
862     return m_intervalArena.get();
863 }
864
865 bool RenderView::backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const
866 {
867     // FIXME: Remove this main frame check. Same concept applies to subframes too.
868     if (!frame()->isMainFrame())
869         return false;
870
871     return m_frameView->hasOpaqueBackground();
872 }
873
874 double RenderView::layoutViewportWidth() const
875 {
876     float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
877     return viewWidth(IncludeScrollbars) / scale;
878 }
879
880 double RenderView::layoutViewportHeight() const
881 {
882     float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
883     return viewHeight(IncludeScrollbars) / scale;
884 }
885
886 } // namespace blink