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 "RenderView.h"
     23 
     24 #include "Document.h"
     25 #include "Element.h"
     26 #include "FloatQuad.h"
     27 #include "Frame.h"
     28 #include "FrameView.h"
     29 #include "GraphicsContext.h"
     30 #include "HTMLFrameOwnerElement.h"
     31 #include "HitTestResult.h"
     32 #include "RenderLayer.h"
     33 #include "RenderSelectionInfo.h"
     34 #include "RenderWidget.h"
     35 #include "RenderWidgetProtector.h"
     36 #include "TransformState.h"
     37 
     38 #if USE(ACCELERATED_COMPOSITING)
     39 #include "RenderLayerCompositor.h"
     40 #endif
     41 
     42 #if defined(ANDROID_LAYOUT) || defined(ANDROID_FIXED_ELEMENTS)
     43 #include "Settings.h"
     44 #endif
     45 
     46 namespace WebCore {
     47 
     48 RenderView::RenderView(Node* node, FrameView* view)
     49     : RenderBlock(node)
     50     , m_frameView(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 {
     61     // Clear our anonymous bit, set because RenderObject assumes
     62     // any renderer with document as the node is anonymous.
     63     setIsAnonymous(false);
     64 
     65     // init RenderObject attributes
     66     setInline(false);
     67 
     68     m_minPreferredLogicalWidth = 0;
     69     m_maxPreferredLogicalWidth = 0;
     70 
     71     setPreferredLogicalWidthsDirty(true, false);
     72 
     73     setPositioned(true); // to 0,0 :)
     74 }
     75 
     76 RenderView::~RenderView()
     77 {
     78 }
     79 
     80 void RenderView::computeLogicalHeight()
     81 {
     82     if (!printing() && m_frameView)
     83         setLogicalHeight(viewLogicalHeight());
     84 }
     85 
     86 void RenderView::computeLogicalWidth()
     87 {
     88     if (!printing() && m_frameView)
     89         setLogicalWidth(viewLogicalWidth());
     90 #ifdef ANDROID_LAYOUT
     91     setVisibleWidth(m_frameView->textWrapWidth());
     92 #endif
     93 }
     94 
     95 void RenderView::computePreferredLogicalWidths()
     96 {
     97     ASSERT(preferredLogicalWidthsDirty());
     98 
     99     RenderBlock::computePreferredLogicalWidths();
    100 
    101     m_maxPreferredLogicalWidth = m_minPreferredLogicalWidth;
    102 }
    103 
    104 bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const
    105 {
    106     return child->isBox();
    107 }
    108 
    109 void RenderView::layout()
    110 {
    111     if (!document()->paginated())
    112         setPageLogicalHeight(0);
    113 
    114     if (printing())
    115         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
    116 
    117     // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
    118     bool relayoutChildren = !printing() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
    119     if (relayoutChildren) {
    120         setChildNeedsLayout(true, false);
    121         for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
    122             if (child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent())
    123                 child->setChildNeedsLayout(true, false);
    124         }
    125     }
    126 
    127     ASSERT(!m_layoutState);
    128     LayoutState state;
    129     // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
    130     state.m_clipped = false;
    131     state.m_pageLogicalHeight = m_pageLogicalHeight;
    132     state.m_pageLogicalHeightChanged = m_pageLogicalHeightChanged;
    133     m_pageLogicalHeightChanged = false;
    134     m_layoutState = &state;
    135 
    136     if (needsLayout())
    137         RenderBlock::layout();
    138 
    139     ASSERT(layoutDelta() == IntSize());
    140     ASSERT(m_layoutStateDisableCount == 0);
    141     ASSERT(m_layoutState == &state);
    142     m_layoutState = 0;
    143     setNeedsLayout(false);
    144 }
    145 
    146 void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const
    147 {
    148     // If a container was specified, and was not 0 or the RenderView,
    149     // then we should have found it by now.
    150     ASSERT_UNUSED(repaintContainer, !repaintContainer || repaintContainer == this);
    151 
    152     if (useTransforms && shouldUseTransformFromContainer(0)) {
    153         TransformationMatrix t;
    154         getTransformFromContainer(0, IntSize(), t);
    155         transformState.applyTransform(t);
    156     }
    157 
    158     if (fixed && m_frameView)
    159         transformState.move(m_frameView->scrollOffsetForFixedPosition());
    160 }
    161 
    162 void RenderView::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const
    163 {
    164     if (fixed && m_frameView)
    165         transformState.move(-m_frameView->scrollOffsetForFixedPosition());
    166 
    167     if (useTransforms && shouldUseTransformFromContainer(0)) {
    168         TransformationMatrix t;
    169         getTransformFromContainer(0, IntSize(), t);
    170         transformState.applyTransform(t);
    171     }
    172 }
    173 
    174 void RenderView::paint(PaintInfo& paintInfo, int tx, int ty)
    175 {
    176     // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
    177     ASSERT(!needsLayout());
    178     paintObject(paintInfo, tx, ty);
    179 }
    180 
    181 static inline bool isComposited(RenderObject* object)
    182 {
    183     return object->hasLayer() && toRenderBoxModelObject(object)->layer()->isComposited();
    184 }
    185 
    186 static inline bool rendererObscuresBackground(RenderObject* object)
    187 {
    188     return object && object->style()->visibility() == VISIBLE
    189         && object->style()->opacity() == 1
    190         && !object->style()->hasTransform()
    191         && !isComposited(object);
    192 }
    193 
    194 void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int, int)
    195 {
    196     // Check to see if we are enclosed by a layer that requires complex painting rules.  If so, we cannot blit
    197     // when scrolling, and we need to use slow repaints.  Examples of layers that require this are transparent layers,
    198     // layers with reflections, or transformed layers.
    199     // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being inside
    200     // a transform, transparency layer, etc.
    201     Element* elt;
    202     for (elt = document()->ownerElement(); view() && elt && elt->renderer(); elt = elt->document()->ownerElement()) {
    203         RenderLayer* layer = elt->renderer()->enclosingLayer();
    204         if (layer->requiresSlowRepaints()) {
    205             frameView()->setUseSlowRepaints();
    206             break;
    207         }
    208 
    209 #if USE(ACCELERATED_COMPOSITING)
    210         if (RenderLayer* compositingLayer = layer->enclosingCompositingLayer()) {
    211             if (!compositingLayer->backing()->paintingGoesToWindow()) {
    212                 frameView()->setUseSlowRepaints();
    213                 break;
    214             }
    215         }
    216 #endif
    217     }
    218 
    219     if (document()->ownerElement() || !view())
    220         return;
    221 
    222     bool rootFillsViewport = false;
    223     Node* documentElement = document()->documentElement();
    224     if (RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0) {
    225         // The document element's renderer is currently forced to be a block, but may not always be.
    226         RenderBox* rootBox = rootRenderer->isBox() ? toRenderBox(rootRenderer) : 0;
    227         rootFillsViewport = rootBox && !rootBox->x() && !rootBox->y() && rootBox->width() >= width() && rootBox->height() >= height();
    228     }
    229 
    230     float pageScaleFactor = 1;
    231     if (Frame* frame = m_frameView->frame())
    232         pageScaleFactor = frame->pageScaleFactor();
    233 
    234     // If painting will entirely fill the view, no need to fill the background.
    235     if (rootFillsViewport && rendererObscuresBackground(firstChild()) && pageScaleFactor >= 1)
    236         return;
    237 
    238     // This code typically only executes if the root element's visibility has been set to hidden,
    239     // if there is a transform on the <html>, or if there is a page scale factor less than 1.
    240     // Only fill with the base background color (typically white) if we're the root document,
    241     // since iframes/frames with no background in the child document should show the parent's background.
    242     if (frameView()->isTransparent()) // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being transparent.
    243         frameView()->setUseSlowRepaints(); // The parent must show behind the child.
    244     else {
    245         Color baseColor = frameView()->baseBackgroundColor();
    246         if (baseColor.alpha() > 0) {
    247             CompositeOperator previousOperator = paintInfo.context->compositeOperation();
    248             paintInfo.context->setCompositeOperation(CompositeCopy);
    249             paintInfo.context->fillRect(paintInfo.rect, baseColor, style()->colorSpace());
    250             paintInfo.context->setCompositeOperation(previousOperator);
    251         } else
    252             paintInfo.context->clearRect(paintInfo.rect);
    253     }
    254 }
    255 
    256 bool RenderView::shouldRepaint(const IntRect& r) const
    257 {
    258     if (printing() || r.width() == 0 || r.height() == 0)
    259         return false;
    260 
    261     if (!m_frameView)
    262         return false;
    263 
    264     return true;
    265 }
    266 
    267 void RenderView::repaintViewRectangle(const IntRect& ur, bool immediate)
    268 {
    269     if (!shouldRepaint(ur))
    270         return;
    271 
    272     // We always just invalidate the root view, since we could be an iframe that is clipped out
    273     // or even invisible.
    274     Element* elt = document()->ownerElement();
    275     if (!elt)
    276         m_frameView->repaintContentRectangle(ur, immediate);
    277     else if (RenderBox* obj = elt->renderBox()) {
    278         IntRect vr = viewRect();
    279         IntRect r = intersection(ur, vr);
    280 
    281         // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
    282         // rectangle.
    283         r.move(-vr.x(), -vr.y());
    284 
    285         // FIXME: Hardcoded offsets here are not good.
    286         r.move(obj->borderLeft() + obj->paddingLeft(),
    287                obj->borderTop() + obj->paddingTop());
    288         obj->repaintRectangle(r, immediate);
    289     }
    290 }
    291 
    292 void RenderView::repaintRectangleInViewAndCompositedLayers(const IntRect& ur, bool immediate)
    293 {
    294     if (!shouldRepaint(ur))
    295         return;
    296 
    297     repaintViewRectangle(ur, immediate);
    298 
    299 #if USE(ACCELERATED_COMPOSITING)
    300     if (compositor()->inCompositingMode())
    301         compositor()->repaintCompositedLayersAbsoluteRect(ur);
    302 #endif
    303 }
    304 
    305 void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
    306 {
    307     // If a container was specified, and was not 0 or the RenderView,
    308     // then we should have found it by now.
    309     ASSERT_UNUSED(repaintContainer, !repaintContainer || repaintContainer == this);
    310 
    311     if (printing())
    312         return;
    313 
    314     if (style()->isFlippedBlocksWritingMode()) {
    315         // We have to flip by hand since the view's logical height has not been determined.  We
    316         // can use the viewport width and height.
    317         if (style()->isHorizontalWritingMode())
    318             rect.setY(viewHeight() - rect.maxY());
    319         else
    320             rect.setX(viewWidth() - rect.maxX());
    321     }
    322 
    323     if (fixed && m_frameView)
    324         rect.move(m_frameView->scrollXForFixedPosition(), m_frameView->scrollYForFixedPosition());
    325 
    326     // Apply our transform if we have one (because of full page zooming).
    327     if (m_layer && m_layer->transform())
    328         rect = m_layer->transform()->mapRect(rect);
    329 }
    330 
    331 void RenderView::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
    332 {
    333     rects.append(IntRect(tx, ty, m_layer->width(), m_layer->height()));
    334 }
    335 
    336 void RenderView::absoluteQuads(Vector<FloatQuad>& quads)
    337 {
    338     quads.append(FloatRect(0, 0, m_layer->width(), m_layer->height()));
    339 }
    340 
    341 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)
    342 {
    343     if (!object)
    344         return 0;
    345 
    346     RenderObject* child = object->childAt(offset);
    347     return child ? child : object->nextInPreOrderAfterChildren();
    348 }
    349 
    350 IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
    351 {
    352     document()->updateStyleIfNeeded();
    353 
    354     typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectionMap;
    355     SelectionMap selectedObjects;
    356 
    357     RenderObject* os = m_selectionStart;
    358     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
    359     while (os && os != stop) {
    360         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
    361             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
    362             selectedObjects.set(os, new RenderSelectionInfo(os, clipToVisibleContent));
    363             RenderBlock* cb = os->containingBlock();
    364             while (cb && !cb->isRenderView()) {
    365                 RenderSelectionInfo* blockInfo = selectedObjects.get(cb);
    366                 if (blockInfo)
    367                     break;
    368                 selectedObjects.set(cb, new RenderSelectionInfo(cb, clipToVisibleContent));
    369                 cb = cb->containingBlock();
    370             }
    371         }
    372 
    373         os = os->nextInPreOrder();
    374     }
    375 
    376     // Now create a single bounding box rect that encloses the whole selection.
    377     IntRect selRect;
    378     SelectionMap::iterator end = selectedObjects.end();
    379     for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
    380         RenderSelectionInfo* info = i->second;
    381         // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
    382         IntRect currRect = info->rect();
    383         if (RenderBoxModelObject* repaintContainer = info->repaintContainer()) {
    384             FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
    385             currRect = absQuad.enclosingBoundingBox();
    386         }
    387         selRect.unite(currRect);
    388         delete info;
    389     }
    390     return selRect;
    391 }
    392 
    393 #if USE(ACCELERATED_COMPOSITING)
    394 // Compositing layer dimensions take outline size into account, so we have to recompute layer
    395 // bounds when it changes.
    396 // FIXME: This is ugly; it would be nice to have a better way to do this.
    397 void RenderView::setMaximalOutlineSize(int o)
    398 {
    399     if (o != m_maximalOutlineSize) {
    400         m_maximalOutlineSize = o;
    401 
    402         // maximalOutlineSize affects compositing layer dimensions.
    403         compositor()->setCompositingLayersNeedRebuild();    // FIXME: this really just needs to be a geometry update.
    404     }
    405 }
    406 #endif
    407 
    408 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
    409 {
    410     // Make sure both our start and end objects are defined.
    411     // Check www.msnbc.com and try clicking around to find the case where this happened.
    412     if ((start && !end) || (end && !start))
    413         return;
    414 
    415     // Just return if the selection hasn't changed.
    416     if (m_selectionStart == start && m_selectionStartPos == startPos &&
    417         m_selectionEnd == end && m_selectionEndPos == endPos)
    418         return;
    419 
    420     // Record the old selected objects.  These will be used later
    421     // when we compare against the new selected objects.
    422     int oldStartPos = m_selectionStartPos;
    423     int oldEndPos = m_selectionEndPos;
    424 
    425     // Objects each have a single selection rect to examine.
    426     typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectedObjectMap;
    427     SelectedObjectMap oldSelectedObjects;
    428     SelectedObjectMap newSelectedObjects;
    429 
    430     // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
    431     // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
    432     // the union of those rects might remain the same even when changes have occurred.
    433     typedef HashMap<RenderBlock*, RenderBlockSelectionInfo*> SelectedBlockMap;
    434     SelectedBlockMap oldSelectedBlocks;
    435     SelectedBlockMap newSelectedBlocks;
    436 
    437     RenderObject* os = m_selectionStart;
    438     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
    439     while (os && os != stop) {
    440         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
    441             // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
    442             oldSelectedObjects.set(os, new RenderSelectionInfo(os, true));
    443             if (blockRepaintMode == RepaintNewXOROld) {
    444                 RenderBlock* cb = os->containingBlock();
    445                 while (cb && !cb->isRenderView()) {
    446                     RenderBlockSelectionInfo* blockInfo = oldSelectedBlocks.get(cb);
    447                     if (blockInfo)
    448                         break;
    449                     oldSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
    450                     cb = cb->containingBlock();
    451                 }
    452             }
    453         }
    454 
    455         os = os->nextInPreOrder();
    456     }
    457 
    458     // Now clear the selection.
    459     SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
    460     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i)
    461         i->first->setSelectionState(SelectionNone);
    462 
    463     // set selection start and end
    464     m_selectionStart = start;
    465     m_selectionStartPos = startPos;
    466     m_selectionEnd = end;
    467     m_selectionEndPos = endPos;
    468 
    469     // Update the selection status of all objects between m_selectionStart and m_selectionEnd
    470     if (start && start == end)
    471         start->setSelectionState(SelectionBoth);
    472     else {
    473         if (start)
    474             start->setSelectionState(SelectionStart);
    475         if (end)
    476             end->setSelectionState(SelectionEnd);
    477     }
    478 
    479     RenderObject* o = start;
    480     stop = rendererAfterPosition(end, endPos);
    481 
    482     while (o && o != stop) {
    483         if (o != start && o != end && o->canBeSelectionLeaf())
    484             o->setSelectionState(SelectionInside);
    485         o = o->nextInPreOrder();
    486     }
    487 
    488     m_layer->clearBlockSelectionGapsBounds();
    489 
    490     // Now that the selection state has been updated for the new objects, walk them again and
    491     // put them in the new objects list.
    492     o = start;
    493     while (o && o != stop) {
    494         if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
    495             newSelectedObjects.set(o, new RenderSelectionInfo(o, true));
    496             RenderBlock* cb = o->containingBlock();
    497             while (cb && !cb->isRenderView()) {
    498                 RenderBlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
    499                 if (blockInfo)
    500                     break;
    501                 newSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
    502                 cb = cb->containingBlock();
    503             }
    504         }
    505 
    506         o = o->nextInPreOrder();
    507     }
    508 
    509     if (!m_frameView) {
    510         // We built the maps, but we aren't going to use them.
    511         // We need to delete the values, otherwise they'll all leak!
    512         deleteAllValues(oldSelectedObjects);
    513         deleteAllValues(newSelectedObjects);
    514         deleteAllValues(oldSelectedBlocks);
    515         deleteAllValues(newSelectedBlocks);
    516         return;
    517     }
    518 
    519     m_frameView->beginDeferredRepaints();
    520 
    521     // Have any of the old selected objects changed compared to the new selection?
    522     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
    523         RenderObject* obj = i->first;
    524         RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
    525         RenderSelectionInfo* oldInfo = i->second;
    526         if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state() ||
    527             (m_selectionStart == obj && oldStartPos != m_selectionStartPos) ||
    528             (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
    529             oldInfo->repaint();
    530             if (newInfo) {
    531                 newInfo->repaint();
    532                 newSelectedObjects.remove(obj);
    533                 delete newInfo;
    534             }
    535         }
    536         delete oldInfo;
    537     }
    538 
    539     // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
    540     SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
    541     for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i) {
    542         RenderSelectionInfo* newInfo = i->second;
    543         newInfo->repaint();
    544         delete newInfo;
    545     }
    546 
    547     // Have any of the old blocks changed?
    548     SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
    549     for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
    550         RenderBlock* block = i->first;
    551         RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
    552         RenderBlockSelectionInfo* oldInfo = i->second;
    553         if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
    554             oldInfo->repaint();
    555             if (newInfo) {
    556                 newInfo->repaint();
    557                 newSelectedBlocks.remove(block);
    558                 delete newInfo;
    559             }
    560         }
    561         delete oldInfo;
    562     }
    563 
    564     // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
    565     SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
    566     for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i) {
    567         RenderBlockSelectionInfo* newInfo = i->second;
    568         newInfo->repaint();
    569         delete newInfo;
    570     }
    571 
    572     m_frameView->endDeferredRepaints();
    573 }
    574 
    575 void RenderView::clearSelection()
    576 {
    577     m_layer->repaintBlockSelectionGaps();
    578     setSelection(0, -1, 0, -1, RepaintNewMinusOld);
    579 }
    580 
    581 void RenderView::selectionStartEnd(int& startPos, int& endPos) const
    582 {
    583     startPos = m_selectionStartPos;
    584     endPos = m_selectionEndPos;
    585 }
    586 
    587 bool RenderView::printing() const
    588 {
    589     return document()->printing();
    590 }
    591 
    592 size_t RenderView::getRetainedWidgets(Vector<RenderWidget*>& renderWidgets)
    593 {
    594     size_t size = m_widgets.size();
    595 
    596     renderWidgets.reserveCapacity(size);
    597 
    598     RenderWidgetSet::const_iterator end = m_widgets.end();
    599     for (RenderWidgetSet::const_iterator it = m_widgets.begin(); it != end; ++it) {
    600         renderWidgets.uncheckedAppend(*it);
    601         (*it)->ref();
    602     }
    603 
    604     return size;
    605 }
    606 
    607 void RenderView::releaseWidgets(Vector<RenderWidget*>& renderWidgets)
    608 {
    609     size_t size = renderWidgets.size();
    610 
    611     for (size_t i = 0; i < size; ++i)
    612         renderWidgets[i]->deref(renderArena());
    613 }
    614 
    615 void RenderView::updateWidgetPositions()
    616 {
    617     // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
    618     // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
    619     // alive during enumeration.
    620 
    621     Vector<RenderWidget*> renderWidgets;
    622     size_t size = getRetainedWidgets(renderWidgets);
    623 
    624     for (size_t i = 0; i < size; ++i)
    625         renderWidgets[i]->updateWidgetPosition();
    626 
    627     for (size_t i = 0; i < size; ++i)
    628         renderWidgets[i]->widgetPositionsUpdated();
    629 
    630     releaseWidgets(renderWidgets);
    631 }
    632 
    633 void RenderView::addWidget(RenderWidget* o)
    634 {
    635     m_widgets.add(o);
    636 }
    637 
    638 void RenderView::removeWidget(RenderWidget* o)
    639 {
    640     m_widgets.remove(o);
    641 }
    642 
    643 void RenderView::notifyWidgets(WidgetNotification notification)
    644 {
    645     Vector<RenderWidget*> renderWidgets;
    646     size_t size = getRetainedWidgets(renderWidgets);
    647 
    648     for (size_t i = 0; i < size; ++i)
    649         renderWidgets[i]->notifyWidget(notification);
    650 
    651     releaseWidgets(renderWidgets);
    652 }
    653 
    654 IntRect RenderView::viewRect() const
    655 {
    656     if (printing())
    657         return IntRect(0, 0, width(), height());
    658     if (m_frameView)
    659         return m_frameView->visibleContentRect();
    660     return IntRect();
    661 }
    662 
    663 int RenderView::docTop() const
    664 {
    665     IntRect overflowRect(0, minYLayoutOverflow(), 0, maxYLayoutOverflow() - minYLayoutOverflow());
    666     flipForWritingMode(overflowRect);
    667     if (hasTransform())
    668         overflowRect = layer()->currentTransform().mapRect(overflowRect);
    669     return overflowRect.y();
    670 }
    671 
    672 int RenderView::docBottom() const
    673 {
    674     IntRect overflowRect(layoutOverflowRect());
    675     flipForWritingMode(overflowRect);
    676     if (hasTransform())
    677         overflowRect = layer()->currentTransform().mapRect(overflowRect);
    678     return overflowRect.maxY();
    679 }
    680 
    681 int RenderView::docLeft() const
    682 {
    683     IntRect overflowRect(layoutOverflowRect());
    684     flipForWritingMode(overflowRect);
    685     if (hasTransform())
    686         overflowRect = layer()->currentTransform().mapRect(overflowRect);
    687     return overflowRect.x();
    688 }
    689 
    690 int RenderView::docRight() const
    691 {
    692     IntRect overflowRect(layoutOverflowRect());
    693     flipForWritingMode(overflowRect);
    694     if (hasTransform())
    695         overflowRect = layer()->currentTransform().mapRect(overflowRect);
    696     return overflowRect.maxX();
    697 }
    698 
    699 int RenderView::viewHeight() const
    700 {
    701     int height = 0;
    702     if (!printing() && m_frameView) {
    703         height = m_frameView->layoutHeight();
    704         height = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(height)) : height;
    705     }
    706     return height;
    707 }
    708 
    709 int RenderView::viewWidth() const
    710 {
    711     int width = 0;
    712     if (!printing() && m_frameView) {
    713         width = m_frameView->layoutWidth();
    714         width = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(width)) : width;
    715     }
    716     return width;
    717 }
    718 
    719 float RenderView::zoomFactor() const
    720 {
    721     Frame* frame = m_frameView->frame();
    722     return frame ? frame->pageZoomFactor() : 1;
    723 }
    724 
    725 void RenderView::pushLayoutState(RenderObject* root)
    726 {
    727     ASSERT(m_layoutStateDisableCount == 0);
    728     ASSERT(m_layoutState == 0);
    729 
    730     m_layoutState = new (renderArena()) LayoutState(root);
    731 }
    732 
    733 bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
    734 {
    735     RenderObject* o = renderer;
    736     while (o) {
    737         if (o->hasColumns() || o->hasTransform() || o->hasReflection())
    738             return true;
    739         o = o->container();
    740     }
    741     return false;
    742 }
    743 
    744 void RenderView::updateHitTestResult(HitTestResult& result, const IntPoint& point)
    745 {
    746     if (result.innerNode())
    747         return;
    748 
    749     Node* node = document()->documentElement();
    750     if (node) {
    751         result.setInnerNode(node);
    752         if (!result.innerNonSharedNode())
    753             result.setInnerNonSharedNode(node);
    754         result.setLocalPoint(point);
    755     }
    756 }
    757 
    758 // FIXME: This function is obsolete and only used by embedded WebViews inside AppKit NSViews.
    759 // Do not add callers of this function!
    760 // The idea here is to take into account what object is moving the pagination point, and
    761 // thus choose the best place to chop it.
    762 void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
    763 {
    764     // Nobody else can set a page break once we have a forced break.
    765     if (m_legacyPrinting.m_forcedPageBreak)
    766         return;
    767 
    768     // Forced breaks always win over unforced breaks.
    769     if (forcedBreak) {
    770         m_legacyPrinting.m_forcedPageBreak = true;
    771         m_legacyPrinting.m_bestTruncatedAt = y;
    772         return;
    773     }
    774 
    775     // Prefer the widest object that tries to move the pagination point
    776     IntRect boundingBox = forRenderer->borderBoundingBox();
    777     if (boundingBox.width() > m_legacyPrinting.m_truncatorWidth) {
    778         m_legacyPrinting.m_truncatorWidth = boundingBox.width();
    779         m_legacyPrinting.m_bestTruncatedAt = y;
    780     }
    781 }
    782 
    783 #if USE(ACCELERATED_COMPOSITING)
    784 bool RenderView::usesCompositing() const
    785 {
    786     return m_compositor && m_compositor->inCompositingMode();
    787 }
    788 
    789 RenderLayerCompositor* RenderView::compositor()
    790 {
    791     if (!m_compositor)
    792         m_compositor.set(new RenderLayerCompositor(this));
    793 
    794     return m_compositor.get();
    795 }
    796 #endif
    797 
    798 void RenderView::didMoveOnscreen()
    799 {
    800 #if USE(ACCELERATED_COMPOSITING)
    801     if (m_compositor)
    802         m_compositor->didMoveOnscreen();
    803 #endif
    804 }
    805 
    806 void RenderView::willMoveOffscreen()
    807 {
    808 #if USE(ACCELERATED_COMPOSITING)
    809     if (m_compositor)
    810         m_compositor->willMoveOffscreen();
    811 #endif
    812 }
    813 
    814 } // namespace WebCore
    815