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