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