251659fc10fbe7decb4b395c00fbd938a551aa87
[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 "FrameSelection.h"
31 #include "FrameView.h"
32 #include "GraphicsContext.h"
33 #include "HTMLFrameOwnerElement.h"
34 #include "HTMLIFrameElement.h"
35 #include "HitTestResult.h"
36 #include "Page.h"
37 #include "RenderGeometryMap.h"
38 #include "RenderLayer.h"
39 #include "RenderLayerBacking.h"
40 #include "RenderNamedFlowThread.h"
41 #include "RenderSelectionInfo.h"
42 #include "RenderWidget.h"
43 #include "RenderWidgetProtector.h"
44 #include "StyleInheritedData.h"
45 #include "TransformState.h"
46 #include <wtf/StackStats.h>
47
48 #if USE(ACCELERATED_COMPOSITING)
49 #include "RenderLayerCompositor.h"
50 #endif
51
52 #if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
53 #include "CustomFilterGlobalContext.h"
54 #endif
55
56 namespace WebCore {
57
58 RenderView::RenderView(Document* document)
59     : RenderBlock(document)
60     , m_frameView(document->view())
61     , m_selectionStart(0)
62     , m_selectionEnd(0)
63     , m_selectionStartPos(-1)
64     , m_selectionEndPos(-1)
65     , m_maximalOutlineSize(0)
66     , m_pageLogicalHeight(0)
67     , m_pageLogicalHeightChanged(false)
68     , m_layoutState(0)
69     , m_layoutStateDisableCount(0)
70     , m_renderQuoteHead(0)
71     , m_renderCounterCount(0)
72     , m_selectionWasCaret(false)
73 {
74     // init RenderObject attributes
75     setInline(false);
76     
77     m_minPreferredLogicalWidth = 0;
78     m_maxPreferredLogicalWidth = 0;
79
80     setPreferredLogicalWidthsDirty(true, MarkOnlyThis);
81     
82     setPositionState(AbsolutePosition); // to 0,0 :)
83 }
84
85 RenderView::~RenderView()
86 {
87 }
88
89 bool RenderView::hitTest(const HitTestRequest& request, HitTestResult& result)
90 {
91     return hitTest(request, result.hitTestLocation(), result);
92 }
93
94 bool RenderView::hitTest(const HitTestRequest& request, const HitTestLocation& location, HitTestResult& result)
95 {
96     if (layer()->hitTest(request, location, result))
97         return true;
98
99     // FIXME: Consider if this test should be done unconditionally.
100     if (request.allowsFrameScrollbars() && m_frameView) {
101         // ScrollView scrollbars are not the same as RenderLayer scrollbars tested by RenderLayer::hitTestOverflowControls,
102         // so we need to test ScrollView scrollbars separately here.
103         Scrollbar* frameScrollbar = m_frameView->scrollbarAtPoint(location.roundedPoint());
104         if (frameScrollbar) {
105             result.setScrollbar(frameScrollbar);
106             return true;
107         }
108     }
109
110     return false;
111 }
112
113 void RenderView::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit, LogicalExtentComputedValues& computedValues) const
114 {
115     computedValues.m_extent = (!shouldUsePrintingLayout() && m_frameView) ? LayoutUnit(viewLogicalHeight()) : logicalHeight;
116 }
117
118 void RenderView::updateLogicalWidth()
119 {
120     if (!shouldUsePrintingLayout() && m_frameView)
121         setLogicalWidth(viewLogicalWidth());
122 }
123
124 LayoutUnit RenderView::availableLogicalHeight(AvailableLogicalHeightType heightType) 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(heightType);
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 static RenderBox* enclosingSeamlessRenderer(Document* doc)
160 {
161     if (!doc)
162         return 0;
163     Element* ownerElement = doc->seamlessParentIFrame();
164     if (!ownerElement)
165         return 0;
166     return ownerElement->renderBox();
167 }
168
169 void RenderView::addChild(RenderObject* newChild, RenderObject* beforeChild)
170 {
171     // Seamless iframes are considered part of an enclosing render flow thread from the parent document. This is necessary for them to look
172     // up regions in the parent document during layout.
173     if (newChild && !newChild->isRenderFlowThread()) {
174         RenderBox* seamlessBox = enclosingSeamlessRenderer(document());
175         if (seamlessBox && seamlessBox->flowThreadContainingBlock())
176             newChild->setFlowThreadState(seamlessBox->flowThreadState());
177     }
178     RenderBlock::addChild(newChild, beforeChild);
179 }
180
181 bool RenderView::initializeLayoutState(LayoutState& state)
182 {
183     bool isSeamlessAncestorInFlowThread = false;
184
185     // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
186     state.m_clipped = false;
187     
188     // Check the writing mode of the seamless ancestor. It has to match our document's writing mode, or we won't inherit any
189     // pagination information.
190     RenderBox* seamlessAncestor = enclosingSeamlessRenderer(document());
191     LayoutState* seamlessLayoutState = seamlessAncestor ? seamlessAncestor->view()->layoutState() : 0;
192     bool shouldInheritPagination = seamlessLayoutState && !m_pageLogicalHeight && seamlessAncestor->style()->writingMode() == style()->writingMode();
193     
194     state.m_pageLogicalHeight = shouldInheritPagination ? seamlessLayoutState->m_pageLogicalHeight : m_pageLogicalHeight;
195     state.m_pageLogicalHeightChanged = shouldInheritPagination ? seamlessLayoutState->m_pageLogicalHeightChanged : m_pageLogicalHeightChanged;
196     state.m_isPaginated = state.m_pageLogicalHeight;
197     if (state.m_isPaginated && shouldInheritPagination) {
198         // Set up the correct pagination offset. We can use a negative offset in order to push the top of the RenderView into its correct place
199         // on a page. We can take the iframe's offset from the logical top of the first page and make the negative into the pagination offset within the child
200         // view.
201         bool isFlipped = seamlessAncestor->style()->isFlippedBlocksWritingMode();
202         LayoutSize layoutOffset = seamlessLayoutState->layoutOffset();
203         LayoutSize iFrameOffset(layoutOffset.width() + seamlessAncestor->x() + (!isFlipped ? seamlessAncestor->borderLeft() + seamlessAncestor->paddingLeft() :
204             seamlessAncestor->borderRight() + seamlessAncestor->paddingRight()),
205             layoutOffset.height() + seamlessAncestor->y() + (!isFlipped ? seamlessAncestor->borderTop() + seamlessAncestor->paddingTop() :
206             seamlessAncestor->borderBottom() + seamlessAncestor->paddingBottom()));
207         
208         LayoutSize offsetDelta = seamlessLayoutState->m_pageOffset - iFrameOffset;
209         state.m_pageOffset = offsetDelta;
210         
211         // Set the current render flow thread to point to our ancestor. This will allow the seamless document to locate the correct
212         // regions when doing a layout.
213         if (seamlessAncestor->flowThreadContainingBlock()) {
214             flowThreadController()->setCurrentRenderFlowThread(seamlessAncestor->view()->flowThreadController()->currentRenderFlowThread());
215             isSeamlessAncestorInFlowThread = true;
216         }
217     }
218
219     // FIXME: We need to make line grids and exclusions work with seamless iframes as well here. Basically all layout state information needs
220     // to propagate here and not just pagination information.
221     return isSeamlessAncestorInFlowThread;
222 }
223
224 // The algorithm below assumes this is a full layout. In case there are previously computed values for regions, supplemental steps are taken
225 // to ensure the results are the same as those obtained from a full layout (i.e. the auto-height regions from all the flows are marked as needing
226 // layout).
227 // 1. The flows are laid out from the outer flow to the inner flow. This successfully computes the outer non-auto-height regions size so the 
228 // inner flows have the necessary information to correctly fragment the content.
229 // 2. The flows are laid out from the inner flow to the outer flow. After an inner flow is laid out it goes into the constrained layout phase
230 // and marks the auto-height regions they need layout. This means the outer flows will relayout if they depend on regions with auto-height regions
231 // belonging to inner flows. This step will correctly set the computedAutoHeight for the auto-height regions. It's possible for non-auto-height
232 // regions to relayout if they depend on auto-height regions. This will invalidate the inner flow threads and mark them as needing layout.
233 // 3. The last step is to do one last layout if there are pathological dependencies between non-auto-height regions and auto-height regions
234 // as detected in the previous step.
235 void RenderView::layoutContentInAutoLogicalHeightRegions(const LayoutState& state)
236 {
237     // We need to invalidate all the flows with auto-height regions if one such flow needs layout.
238     // If none is found we do a layout a check back again afterwards.
239     if (!flowThreadController()->updateFlowThreadsNeedingLayout()) {
240         // Do a first layout of the content. In some cases more layouts are not needed (e.g. only flows with non-auto-height regions have changed).
241         layoutContent(state);
242
243         // If we find no named flow needing a two step layout after the first layout, exit early.
244         // Otherwise, initiate the two step layout algorithm and recompute all the flows.
245         if (!flowThreadController()->updateFlowThreadsNeedingTwoStepLayout())
246             return;
247     }
248
249     // Layout to recompute all the named flows with auto-height regions.
250     layoutContent(state);
251
252     // Propagate the computed auto-height values upwards.
253     // Non-auto-height regions may invalidate the flow thread because they depended on auto-height regions, but that's ok.
254     flowThreadController()->updateFlowThreadsIntoConstrainedPhase();
255
256     // Do one last layout that should update the auto-height regions found in the main flow
257     // and solve pathological dependencies between regions (e.g. a non-auto-height region depending
258     // on an auto-height one).
259     if (needsLayout())
260         layoutContent(state);
261 }
262
263 void RenderView::layout()
264 {
265     StackStats::LayoutCheckPoint layoutCheckPoint;
266     if (!document()->paginated())
267         setPageLogicalHeight(0);
268
269     if (shouldUsePrintingLayout())
270         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
271
272     // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
273     bool relayoutChildren = !shouldUsePrintingLayout() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
274     if (relayoutChildren) {
275         setChildNeedsLayout(true, MarkOnlyThis);
276         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
277             if ((child->isBox() && (toRenderBox(child)->hasRelativeLogicalHeight() || toRenderBox(child)->hasViewportPercentageLogicalHeight()))
278                     || child->style()->logicalHeight().isPercent()
279                     || child->style()->logicalMinHeight().isPercent()
280                     || child->style()->logicalMaxHeight().isPercent()
281                     || child->style()->logicalHeight().isViewportPercentage()
282                     || child->style()->logicalMinHeight().isViewportPercentage()
283                     || child->style()->logicalMaxHeight().isViewportPercentage()
284 #if ENABLE(SVG)
285                     || child->isSVGRoot()
286 #endif
287                 )
288                 child->setChildNeedsLayout(true, MarkOnlyThis);
289         }
290     }
291
292     ASSERT(!m_layoutState);
293     if (!needsLayout())
294         return;
295
296     LayoutState state;
297     bool isSeamlessAncestorInFlowThread = initializeLayoutState(state);
298
299     m_pageLogicalHeightChanged = false;
300     m_layoutState = &state;
301
302     if (checkTwoPassLayoutForAutoHeightRegions())
303         layoutContentInAutoLogicalHeightRegions(state);
304     else
305         layoutContent(state);
306
307 #ifndef NDEBUG
308     checkLayoutState(state);
309 #endif
310     m_layoutState = 0;
311     setNeedsLayout(false);
312     
313     if (isSeamlessAncestorInFlowThread)
314         flowThreadController()->setCurrentRenderFlowThread(0);
315 }
316
317 LayoutUnit RenderView::pageOrViewLogicalHeight() const
318 {
319     if (document()->printing())
320         return pageLogicalHeight();
321     
322     if (hasColumns() && !style()->hasInlineColumnAxis()) {
323         if (int pageLength = frameView()->pagination().pageLength)
324             return pageLength;
325     }
326
327     return viewLogicalHeight();
328 }
329
330 void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
331 {
332     // If a container was specified, and was not 0 or the RenderView,
333     // then we should have found it by now.
334     ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
335     ASSERT_UNUSED(wasFixed, !wasFixed || *wasFixed == (mode & IsFixed));
336
337     if (!repaintContainer && mode & UseTransforms && shouldUseTransformFromContainer(0)) {
338         TransformationMatrix t;
339         getTransformFromContainer(0, LayoutSize(), t);
340         transformState.applyTransform(t);
341     }
342     
343     if (mode & IsFixed && m_frameView)
344         transformState.move(m_frameView->scrollOffsetForFixedPosition());
345 }
346
347 const RenderObject* RenderView::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
348 {
349     // If a container was specified, and was not 0 or the RenderView,
350     // then we should have found it by now.
351     ASSERT_ARG(ancestorToStopAt, !ancestorToStopAt || ancestorToStopAt == this);
352
353     LayoutSize scrollOffset;
354
355     if (m_frameView)
356         scrollOffset = m_frameView->scrollOffsetForFixedPosition();
357
358     if (!ancestorToStopAt && shouldUseTransformFromContainer(0)) {
359         TransformationMatrix t;
360         getTransformFromContainer(0, LayoutSize(), t);
361         geometryMap.pushView(this, scrollOffset, &t);
362     } else
363         geometryMap.pushView(this, scrollOffset);
364
365     return 0;
366 }
367
368 void RenderView::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
369 {
370     if (mode & IsFixed && m_frameView)
371         transformState.move(m_frameView->scrollOffsetForFixedPosition());
372
373     if (mode & UseTransforms && shouldUseTransformFromContainer(0)) {
374         TransformationMatrix t;
375         getTransformFromContainer(0, LayoutSize(), t);
376         transformState.applyTransform(t);
377     }
378 }
379
380 bool RenderView::requiresColumns(int desiredColumnCount) const
381 {
382     if (m_frameView)
383         return m_frameView->pagination().mode != Pagination::Unpaginated;
384
385     return RenderBlock::requiresColumns(desiredColumnCount);
386 }
387
388 void RenderView::calcColumnWidth()
389 {
390     int columnWidth = contentLogicalWidth();
391     if (m_frameView && style()->hasInlineColumnAxis()) {
392         if (int pageLength = m_frameView->pagination().pageLength)
393             columnWidth = pageLength;
394     }
395     setDesiredColumnCountAndWidth(1, columnWidth);
396 }
397
398 ColumnInfo::PaginationUnit RenderView::paginationUnit() const
399 {
400     if (m_frameView)
401         return m_frameView->pagination().behavesLikeColumns ? ColumnInfo::Column : ColumnInfo::Page;
402
403     return ColumnInfo::Page;
404 }
405
406 void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
407 {
408     // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
409     ASSERT(!needsLayout());
410     // RenderViews should never be called to paint with an offset not on device pixels.
411     ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffset);
412
413     // This avoids painting garbage between columns if there is a column gap.
414     if (m_frameView && m_frameView->pagination().mode != Pagination::Unpaginated && paintInfo.shouldPaintWithinRoot(this))
415         paintInfo.context->fillRect(paintInfo.rect, m_frameView->baseBackgroundColor(), ColorSpaceDeviceRGB);
416
417     paintObject(paintInfo, paintOffset);
418 }
419
420 static inline bool isComposited(RenderObject* object)
421 {
422     return object->hasLayer() && toRenderLayerModelObject(object)->layer()->isComposited();
423 }
424
425 static inline bool rendererObscuresBackground(RenderObject* rootObject)
426 {
427     if (!rootObject)
428         return false;
429     
430     RenderStyle* style = rootObject->style();
431     if (style->visibility() != VISIBLE
432         || style->opacity() != 1
433         || style->hasTransform())
434         return false;
435     
436     if (isComposited(rootObject))
437         return false;
438
439     const RenderObject* rootRenderer = rootObject->rendererForRootBackground();
440     if (rootRenderer->style()->backgroundClip() == TextFillBox)
441         return false;
442
443     return true;
444 }
445
446 void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
447 {
448     if (!paintInfo.shouldPaintWithinRoot(this))
449         return;
450
451     // Check to see if we are enclosed by a layer that requires complex painting rules.  If so, we cannot blit
452     // when scrolling, and we need to use slow repaints.  Examples of layers that require this are transparent layers,
453     // layers with reflections, or transformed layers.
454     // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being inside
455     // a transform, transparency layer, etc.
456     Element* elt;
457     for (elt = document()->ownerElement(); view() && elt && elt->renderer(); elt = elt->document()->ownerElement()) {
458         RenderLayer* layer = elt->renderer()->enclosingLayer();
459         if (layer->cannotBlitToWindow()) {
460             frameView()->setCannotBlitToWindow();
461             break;
462         }
463
464 #if USE(ACCELERATED_COMPOSITING)
465         if (RenderLayer* compositingLayer = layer->enclosingCompositingLayerForRepaint()) {
466             if (!compositingLayer->backing()->paintsIntoWindow()) {
467                 frameView()->setCannotBlitToWindow();
468                 break;
469             }
470         }
471 #endif
472     }
473
474     if (document()->ownerElement() || !view())
475         return;
476
477     if (paintInfo.skipRootBackground())
478         return;
479
480     bool rootFillsViewport = false;
481     bool rootObscuresBackground = false;
482     Node* documentElement = document()->documentElement();
483     if (RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0) {
484         // The document element's renderer is currently forced to be a block, but may not always be.
485         RenderBox* rootBox = rootRenderer->isBox() ? toRenderBox(rootRenderer) : 0;
486         rootFillsViewport = rootBox && !rootBox->x() && !rootBox->y() && rootBox->width() >= width() && rootBox->height() >= height();
487         rootObscuresBackground = rendererObscuresBackground(rootRenderer);
488     }
489     
490     Page* page = document()->page();
491     float pageScaleFactor = page ? page->pageScaleFactor() : 1;
492
493     // If painting will entirely fill the view, no need to fill the background.
494     if (rootFillsViewport && rootObscuresBackground && pageScaleFactor >= 1)
495         return;
496
497     // This code typically only executes if the root element's visibility has been set to hidden,
498     // if there is a transform on the <html>, or if there is a page scale factor less than 1.
499     // Only fill with the base background color (typically white) if we're the root document, 
500     // since iframes/frames with no background in the child document should show the parent's background.
501     if (frameView()->isTransparent()) // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being transparent.
502         frameView()->setCannotBlitToWindow(); // The parent must show behind the child.
503     else {
504         Color baseColor = frameView()->baseBackgroundColor();
505         if (baseColor.alpha()) {
506             CompositeOperator previousOperator = paintInfo.context->compositeOperation();
507             paintInfo.context->setCompositeOperation(CompositeCopy);
508             paintInfo.context->fillRect(paintInfo.rect, baseColor, style()->colorSpace());
509             paintInfo.context->setCompositeOperation(previousOperator);
510         } else
511             paintInfo.context->clearRect(paintInfo.rect);
512     }
513 }
514
515 bool RenderView::shouldRepaint(const LayoutRect& r) const
516 {
517     if (printing() || r.width() == 0 || r.height() == 0)
518         return false;
519
520     if (!m_frameView)
521         return false;
522
523     if (m_frameView->repaintsDisabled())
524         return false;
525
526     return true;
527 }
528
529 void RenderView::repaintViewRectangle(const LayoutRect& ur, bool immediate) const
530 {
531     if (!shouldRepaint(ur))
532         return;
533
534     // We always just invalidate the root view, since we could be an iframe that is clipped out
535     // or even invisible.
536     Element* elt = document()->ownerElement();
537     if (!elt)
538         m_frameView->repaintContentRectangle(pixelSnappedIntRect(ur), immediate);
539     else if (RenderBox* obj = elt->renderBox()) {
540         LayoutRect vr = viewRect();
541         LayoutRect r = intersection(ur, vr);
542         
543         // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
544         // rectangle.
545         r.moveBy(-vr.location());
546
547         // FIXME: Hardcoded offsets here are not good.
548         r.moveBy(obj->contentBoxRect().location());
549         obj->repaintRectangle(r, immediate);
550     }
551 }
552
553 void RenderView::repaintRectangleInViewAndCompositedLayers(const LayoutRect& ur, bool immediate)
554 {
555     if (!shouldRepaint(ur))
556         return;
557
558     repaintViewRectangle(ur, immediate);
559     
560 #if USE(ACCELERATED_COMPOSITING)
561     if (compositor()->inCompositingMode()) {
562         IntRect repaintRect = pixelSnappedIntRect(ur);
563         compositor()->repaintCompositedLayers(&repaintRect);
564     }
565 #endif
566 }
567
568 void RenderView::repaintViewAndCompositedLayers()
569 {
570     repaint();
571     
572 #if USE(ACCELERATED_COMPOSITING)
573     if (compositor()->inCompositingMode())
574         compositor()->repaintCompositedLayers();
575 #endif
576 }
577
578 LayoutRect RenderView::visualOverflowRect() const
579 {
580     if (m_frameView->paintsEntireContents())
581         return layoutOverflowRect();
582
583     return RenderBlock::visualOverflowRect();
584 }
585
586 void RenderView::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
587 {
588     // If a container was specified, and was not 0 or the RenderView,
589     // then we should have found it by now.
590     ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
591
592     if (printing())
593         return;
594
595     if (style()->isFlippedBlocksWritingMode()) {
596         // We have to flip by hand since the view's logical height has not been determined.  We
597         // can use the viewport width and height.
598         if (style()->isHorizontalWritingMode())
599             rect.setY(viewHeight() - rect.maxY());
600         else
601             rect.setX(viewWidth() - rect.maxX());
602     }
603
604     if (fixed && m_frameView)
605         rect.move(m_frameView->scrollOffsetForFixedPosition());
606         
607     // Apply our transform if we have one (because of full page zooming).
608     if (!repaintContainer && layer() && layer()->transform())
609         rect = layer()->transform()->mapRect(rect);
610 }
611
612 void RenderView::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
613 {
614     rects.append(pixelSnappedIntRect(accumulatedOffset, layer()->size()));
615 }
616
617 void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
618 {
619     if (wasFixed)
620         *wasFixed = false;
621     quads.append(FloatRect(FloatPoint(), layer()->size()));
622 }
623
624 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)
625 {
626     if (!object)
627         return 0;
628
629     RenderObject* child = object->childAt(offset);
630     return child ? child : object->nextInPreOrderAfterChildren();
631 }
632
633 IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
634 {
635     document()->updateStyleIfNeeded();
636
637     typedef HashMap<RenderObject*, OwnPtr<RenderSelectionInfo> > SelectionMap;
638     SelectionMap selectedObjects;
639
640     RenderObject* os = m_selectionStart;
641     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
642     while (os && os != stop) {
643         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
644             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
645             selectedObjects.set(os, adoptPtr(new RenderSelectionInfo(os, clipToVisibleContent)));
646             RenderBlock* cb = os->containingBlock();
647             while (cb && !cb->isRenderView()) {
648                 OwnPtr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).iterator->value;
649                 if (blockInfo)
650                     break;
651                 blockInfo = adoptPtr(new RenderSelectionInfo(cb, clipToVisibleContent));
652                 cb = cb->containingBlock();
653             }
654         }
655
656         os = os->nextInPreOrder();
657     }
658
659     // Now create a single bounding box rect that encloses the whole selection.
660     LayoutRect selRect;
661     SelectionMap::iterator end = selectedObjects.end();
662     for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
663         RenderSelectionInfo* info = i->value.get();
664         // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
665         LayoutRect currRect = info->rect();
666         if (RenderLayerModelObject* repaintContainer = info->repaintContainer()) {
667             FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
668             currRect = absQuad.enclosingBoundingBox(); 
669         }
670         selRect.unite(currRect);
671     }
672     return pixelSnappedIntRect(selRect);
673 }
674
675 void RenderView::repaintSelection() const
676 {
677     document()->updateStyleIfNeeded();
678
679     HashSet<RenderBlock*> processedBlocks;
680
681     RenderObject* end = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
682     for (RenderObject* o = m_selectionStart; o && o != end; o = o->nextInPreOrder()) {
683         if (!o->canBeSelectionLeaf() && o != m_selectionStart && o != m_selectionEnd)
684             continue;
685         if (o->selectionState() == SelectionNone)
686             continue;
687
688         RenderSelectionInfo(o, true).repaint();
689
690         // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
691         for (RenderBlock* block = o->containingBlock(); block && !block->isRenderView(); block = block->containingBlock()) {
692             if (!processedBlocks.add(block).isNewEntry)
693                 break;
694             RenderSelectionInfo(block, true).repaint();
695         }
696     }
697 }
698
699 #if USE(ACCELERATED_COMPOSITING)
700 // Compositing layer dimensions take outline size into account, so we have to recompute layer
701 // bounds when it changes.
702 // FIXME: This is ugly; it would be nice to have a better way to do this.
703 void RenderView::setMaximalOutlineSize(int o)
704 {
705     if (o != m_maximalOutlineSize) {
706         m_maximalOutlineSize = o;
707
708         // maximalOutlineSize affects compositing layer dimensions.
709         compositor()->setCompositingLayersNeedRebuild();    // FIXME: this really just needs to be a geometry update.
710     }
711 }
712 #endif
713
714 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
715 {
716     // Make sure both our start and end objects are defined.
717     // Check www.msnbc.com and try clicking around to find the case where this happened.
718     if ((start && !end) || (end && !start))
719         return;
720
721     bool caretChanged = m_selectionWasCaret != view()->frame()->selection()->isCaret();
722     m_selectionWasCaret = view()->frame()->selection()->isCaret();
723     // Just return if the selection hasn't changed.
724     if (m_selectionStart == start && m_selectionStartPos == startPos &&
725         m_selectionEnd == end && m_selectionEndPos == endPos && !caretChanged)
726         return;
727
728     if ((start && end) && (start->flowThreadContainingBlock() != end->flowThreadContainingBlock()))
729         return;
730
731     // Record the old selected objects.  These will be used later
732     // when we compare against the new selected objects.
733     int oldStartPos = m_selectionStartPos;
734     int oldEndPos = m_selectionEndPos;
735
736     // Objects each have a single selection rect to examine.
737     typedef HashMap<RenderObject*, OwnPtr<RenderSelectionInfo> > SelectedObjectMap;
738     SelectedObjectMap oldSelectedObjects;
739     SelectedObjectMap newSelectedObjects;
740
741     // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
742     // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
743     // the union of those rects might remain the same even when changes have occurred.
744     typedef HashMap<RenderBlock*, OwnPtr<RenderBlockSelectionInfo> > SelectedBlockMap;
745     SelectedBlockMap oldSelectedBlocks;
746     SelectedBlockMap newSelectedBlocks;
747
748     RenderObject* os = m_selectionStart;
749     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
750     while (os && os != stop) {
751         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
752             // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
753             oldSelectedObjects.set(os, adoptPtr(new RenderSelectionInfo(os, true)));
754             if (blockRepaintMode == RepaintNewXOROld) {
755                 RenderBlock* cb = os->containingBlock();
756                 while (cb && !cb->isRenderView()) {
757                     OwnPtr<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).iterator->value;
758                     if (blockInfo)
759                         break;
760                     blockInfo = adoptPtr(new RenderBlockSelectionInfo(cb));
761                     cb = cb->containingBlock();
762                 }
763             }
764         }
765
766         os = os->nextInPreOrder();
767     }
768
769     // Now clear the selection.
770     SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
771     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i)
772         i->key->setSelectionStateIfNeeded(SelectionNone);
773
774     // set selection start and end
775     m_selectionStart = start;
776     m_selectionStartPos = startPos;
777     m_selectionEnd = end;
778     m_selectionEndPos = endPos;
779
780     // Update the selection status of all objects between m_selectionStart and m_selectionEnd
781     if (start && start == end)
782         start->setSelectionStateIfNeeded(SelectionBoth);
783     else {
784         if (start)
785             start->setSelectionStateIfNeeded(SelectionStart);
786         if (end)
787             end->setSelectionStateIfNeeded(SelectionEnd);
788     }
789
790     RenderObject* o = start;
791     stop = rendererAfterPosition(end, endPos);
792
793     while (o && o != stop) {
794         if (o != start && o != end && o->canBeSelectionLeaf())
795             o->setSelectionStateIfNeeded(SelectionInside);
796         o = o->nextInPreOrder();
797     }
798
799     if (blockRepaintMode != RepaintNothing)
800         layer()->clearBlockSelectionGapsBounds();
801
802     // Now that the selection state has been updated for the new objects, walk them again and
803     // put them in the new objects list.
804     o = start;
805     while (o && o != stop) {
806         if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
807             newSelectedObjects.set(o, adoptPtr(new RenderSelectionInfo(o, true)));
808             RenderBlock* cb = o->containingBlock();
809             while (cb && !cb->isRenderView()) {
810                 OwnPtr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).iterator->value;
811                 if (blockInfo)
812                     break;
813                 blockInfo = adoptPtr(new RenderBlockSelectionInfo(cb));
814                 cb = cb->containingBlock();
815             }
816         }
817
818         o = o->nextInPreOrder();
819     }
820
821     if (!m_frameView || blockRepaintMode == RepaintNothing)
822         return;
823
824     m_frameView->beginDeferredRepaints();
825
826     // Have any of the old selected objects changed compared to the new selection?
827     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
828         RenderObject* obj = i->key;
829         RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
830         RenderSelectionInfo* oldInfo = i->value.get();
831         if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state() ||
832             (m_selectionStart == obj && oldStartPos != m_selectionStartPos) ||
833             (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
834             oldInfo->repaint();
835             if (newInfo) {
836                 newInfo->repaint();
837                 newSelectedObjects.remove(obj);
838             }
839         }
840     }
841
842     // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
843     SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
844     for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i)
845         i->value->repaint();
846
847     // Have any of the old blocks changed?
848     SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
849     for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
850         RenderBlock* block = i->key;
851         RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
852         RenderBlockSelectionInfo* oldInfo = i->value.get();
853         if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
854             oldInfo->repaint();
855             if (newInfo) {
856                 newInfo->repaint();
857                 newSelectedBlocks.remove(block);
858             }
859         }
860     }
861
862     // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
863     SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
864     for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i)
865         i->value->repaint();
866
867     m_frameView->endDeferredRepaints();
868 }
869
870 void RenderView::getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const
871 {
872     startRenderer = m_selectionStart;
873     startOffset = m_selectionStartPos;
874     endRenderer = m_selectionEnd;
875     endOffset = m_selectionEndPos;
876 }
877
878 void RenderView::clearSelection()
879 {
880     layer()->repaintBlockSelectionGaps();
881     setSelection(0, -1, 0, -1, RepaintNewMinusOld);
882 }
883
884 void RenderView::selectionStartEnd(int& startPos, int& endPos) const
885 {
886     startPos = m_selectionStartPos;
887     endPos = m_selectionEndPos;
888 }
889
890 bool RenderView::printing() const
891 {
892     return document()->printing();
893 }
894
895 bool RenderView::shouldUsePrintingLayout() const
896 {
897     if (!printing() || !m_frameView)
898         return false;
899     Frame* frame = m_frameView->frame();
900     return frame && frame->shouldUsePrintingLayout();
901 }
902
903 size_t RenderView::getRetainedWidgets(Vector<RenderWidget*>& renderWidgets)
904 {
905     size_t size = m_widgets.size();
906
907     renderWidgets.reserveCapacity(size);
908
909     RenderWidgetSet::const_iterator end = m_widgets.end();
910     for (RenderWidgetSet::const_iterator it = m_widgets.begin(); it != end; ++it) {
911         renderWidgets.uncheckedAppend(*it);
912         (*it)->ref();
913     }
914     
915     return size;
916 }
917
918 void RenderView::releaseWidgets(Vector<RenderWidget*>& renderWidgets)
919 {
920     size_t size = renderWidgets.size();
921
922     for (size_t i = 0; i < size; ++i)
923         renderWidgets[i]->deref(renderArena());
924 }
925
926 void RenderView::updateWidgetPositions()
927 {
928     // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
929     // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
930     // alive during enumeration.    
931
932     Vector<RenderWidget*> renderWidgets;
933     size_t size = getRetainedWidgets(renderWidgets);
934     
935     for (size_t i = 0; i < size; ++i)
936         renderWidgets[i]->updateWidgetPosition();
937
938     for (size_t i = 0; i < size; ++i)
939         renderWidgets[i]->widgetPositionsUpdated();
940
941     releaseWidgets(renderWidgets);
942 }
943
944 void RenderView::addWidget(RenderWidget* o)
945 {
946     m_widgets.add(o);
947 }
948
949 void RenderView::removeWidget(RenderWidget* o)
950 {
951     m_widgets.remove(o);
952 }
953
954 void RenderView::notifyWidgets(WidgetNotification notification)
955 {
956     Vector<RenderWidget*> renderWidgets;
957     size_t size = getRetainedWidgets(renderWidgets);
958
959     for (size_t i = 0; i < size; ++i)
960         renderWidgets[i]->notifyWidget(notification);
961
962     releaseWidgets(renderWidgets);
963 }
964
965 LayoutRect RenderView::viewRect() const
966 {
967     if (shouldUsePrintingLayout())
968         return LayoutRect(LayoutPoint(), size());
969     if (m_frameView)
970         return m_frameView->visibleContentRect();
971     return LayoutRect();
972 }
973
974
975 IntRect RenderView::unscaledDocumentRect() const
976 {
977     LayoutRect overflowRect(layoutOverflowRect());
978     flipForWritingMode(overflowRect);
979     return pixelSnappedIntRect(overflowRect);
980 }
981
982 bool RenderView::rootBackgroundIsEntirelyFixed() const
983 {
984     RenderObject* rootObject = document()->documentElement() ? document()->documentElement()->renderer() : 0;
985     if (!rootObject)
986         return false;
987
988     RenderObject* rootRenderer = rootObject->rendererForRootBackground();
989     return rootRenderer->hasEntirelyFixedBackground();
990 }
991
992 LayoutRect RenderView::backgroundRect(RenderBox* backgroundRenderer) const
993 {
994     if (!hasColumns())
995         return unscaledDocumentRect();
996
997     ColumnInfo* columnInfo = this->columnInfo();
998     LayoutRect backgroundRect(0, 0, columnInfo->desiredColumnWidth(), columnInfo->columnHeight() * columnInfo->columnCount());
999     if (!isHorizontalWritingMode())
1000         backgroundRect = backgroundRect.transposedRect();
1001     backgroundRenderer->flipForWritingMode(backgroundRect);
1002
1003     return backgroundRect;
1004 }
1005
1006 IntRect RenderView::documentRect() const
1007 {
1008     FloatRect overflowRect(unscaledDocumentRect());
1009     if (hasTransform())
1010         overflowRect = layer()->currentTransform().mapRect(overflowRect);
1011     return IntRect(overflowRect);
1012 }
1013
1014 int RenderView::viewHeight() const
1015 {
1016     int height = 0;
1017     if (!shouldUsePrintingLayout() && m_frameView) {
1018         height = m_frameView->layoutHeight();
1019         height = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(height)) : height;
1020     }
1021     return height;
1022 }
1023
1024 int RenderView::viewWidth() const
1025 {
1026     int width = 0;
1027     if (!shouldUsePrintingLayout() && m_frameView) {
1028         width = m_frameView->layoutWidth();
1029         width = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(width)) : width;
1030     }
1031     return width;
1032 }
1033
1034 int RenderView::viewLogicalHeight() const
1035 {
1036     int height = style()->isHorizontalWritingMode() ? viewHeight() : viewWidth();
1037     return height;
1038 }
1039
1040 float RenderView::zoomFactor() const
1041 {
1042     Frame* frame = m_frameView->frame();
1043     return frame ? frame->pageZoomFactor() : 1;
1044 }
1045
1046 void RenderView::pushLayoutState(RenderObject* root)
1047 {
1048     ASSERT(m_layoutStateDisableCount == 0);
1049     ASSERT(m_layoutState == 0);
1050
1051     pushLayoutStateForCurrentFlowThread(root);
1052     m_layoutState = new (renderArena()) LayoutState(root);
1053 }
1054
1055 bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
1056 {
1057     RenderObject* o = renderer;
1058     while (o) {
1059         if (o->hasColumns() || o->hasTransform() || o->hasReflection())
1060             return true;
1061         o = o->container();
1062     }
1063     return false;
1064 }
1065
1066 void RenderView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
1067 {
1068     if (result.innerNode())
1069         return;
1070
1071     Node* node = document()->documentElement();
1072     if (node) {
1073         result.setInnerNode(node);
1074         if (!result.innerNonSharedNode())
1075             result.setInnerNonSharedNode(node);
1076
1077         LayoutPoint adjustedPoint = point;
1078         offsetForContents(adjustedPoint);
1079
1080         result.setLocalPoint(adjustedPoint);
1081     }
1082 }
1083
1084 // FIXME: This function is obsolete and only used by embedded WebViews inside AppKit NSViews.
1085 // Do not add callers of this function!
1086 // The idea here is to take into account what object is moving the pagination point, and
1087 // thus choose the best place to chop it.
1088 void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
1089 {
1090     // Nobody else can set a page break once we have a forced break.
1091     if (m_legacyPrinting.m_forcedPageBreak)
1092         return;
1093
1094     // Forced breaks always win over unforced breaks.
1095     if (forcedBreak) {
1096         m_legacyPrinting.m_forcedPageBreak = true;
1097         m_legacyPrinting.m_bestTruncatedAt = y;
1098         return;
1099     }
1100
1101     // Prefer the widest object that tries to move the pagination point
1102     IntRect boundingBox = forRenderer->borderBoundingBox();
1103     if (boundingBox.width() > m_legacyPrinting.m_truncatorWidth) {
1104         m_legacyPrinting.m_truncatorWidth = boundingBox.width();
1105         m_legacyPrinting.m_bestTruncatedAt = y;
1106     }
1107 }
1108
1109 #if USE(ACCELERATED_COMPOSITING)
1110 bool RenderView::usesCompositing() const
1111 {
1112     return m_compositor && m_compositor->inCompositingMode();
1113 }
1114
1115 RenderLayerCompositor* RenderView::compositor()
1116 {
1117     if (!m_compositor)
1118         m_compositor = adoptPtr(new RenderLayerCompositor(this));
1119
1120     return m_compositor.get();
1121 }
1122 #endif
1123
1124 void RenderView::setIsInWindow(bool isInWindow)
1125 {
1126 #if USE(ACCELERATED_COMPOSITING)
1127     if (m_compositor)
1128         m_compositor->setIsInWindow(isInWindow);
1129 #endif
1130 }
1131
1132 #if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
1133 CustomFilterGlobalContext* RenderView::customFilterGlobalContext()
1134 {
1135     if (!m_customFilterGlobalContext)
1136         m_customFilterGlobalContext = adoptPtr(new CustomFilterGlobalContext());
1137     return m_customFilterGlobalContext.get();
1138 }
1139 #endif
1140
1141 void RenderView::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
1142 {
1143     RenderBlock::styleDidChange(diff, oldStyle);
1144     if (hasRenderNamedFlowThreads())
1145         flowThreadController()->styleDidChange();
1146 }
1147
1148 bool RenderView::hasRenderNamedFlowThreads() const
1149 {
1150     return m_flowThreadController && m_flowThreadController->hasRenderNamedFlowThreads();
1151 }
1152
1153 bool RenderView::checkTwoPassLayoutForAutoHeightRegions() const
1154 {
1155     return hasRenderNamedFlowThreads() && m_flowThreadController->hasFlowThreadsWithAutoLogicalHeightRegions();
1156 }
1157
1158 FlowThreadController* RenderView::flowThreadController()
1159 {
1160     if (!m_flowThreadController)
1161         m_flowThreadController = FlowThreadController::create(this);
1162
1163     return m_flowThreadController.get();
1164 }
1165
1166 void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject* object)
1167 {
1168     if (!m_flowThreadController)
1169         return;
1170
1171     RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();
1172     if (!currentFlowThread)
1173         return;
1174
1175     currentFlowThread->pushFlowThreadLayoutState(object);
1176 }
1177
1178 void RenderView::popLayoutStateForCurrentFlowThread()
1179 {
1180     if (!m_flowThreadController)
1181         return;
1182
1183     RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();
1184     if (!currentFlowThread)
1185         return;
1186
1187     currentFlowThread->popFlowThreadLayoutState();
1188 }
1189
1190 RenderBlock::IntervalArena* RenderView::intervalArena()
1191 {
1192     if (!m_intervalArena)
1193         m_intervalArena = IntervalArena::create();
1194     return m_intervalArena.get();
1195 }
1196
1197 FragmentationDisabler::FragmentationDisabler(RenderObject* root)
1198 {
1199     RenderView* renderView = root->view();
1200     ASSERT(renderView);
1201
1202     LayoutState* layoutState = renderView->layoutState();
1203
1204     m_root = root;
1205     m_fragmenting = layoutState && layoutState->isPaginated();
1206     m_flowThreadState = m_root->flowThreadState();
1207 #ifndef NDEBUG
1208     m_layoutState = layoutState;
1209 #endif
1210
1211     if (layoutState)
1212         layoutState->m_isPaginated = false;
1213         
1214     if (m_flowThreadState != RenderObject::NotInsideFlowThread)
1215         m_root->setFlowThreadStateIncludingDescendants(RenderObject::NotInsideFlowThread);
1216 }
1217
1218 FragmentationDisabler::~FragmentationDisabler()
1219 {
1220     RenderView* renderView = m_root->view();
1221     ASSERT(renderView);
1222
1223     LayoutState* layoutState = renderView->layoutState();
1224 #ifndef NDEBUG
1225     ASSERT(m_layoutState == layoutState);
1226 #endif
1227
1228     if (layoutState)
1229         layoutState->m_isPaginated = m_fragmenting;
1230         
1231     if (m_flowThreadState != RenderObject::NotInsideFlowThread)
1232         m_root->setFlowThreadStateIncludingDescendants(m_flowThreadState);
1233 }
1234
1235 } // namespace WebCore