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