• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #include "config.h"
22 #include "RenderView.h"
23 
24 #include "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 
RenderView(Node * node,FrameView * view)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 
~RenderView()77 RenderView::~RenderView()
78 {
79 }
80 
calcHeight()81 void RenderView::calcHeight()
82 {
83     if (!printing() && m_frameView)
84         setHeight(viewHeight());
85 }
86 
calcWidth()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 
calcPrefWidths()103 void RenderView::calcPrefWidths()
104 {
105     ASSERT(prefWidthsDirty());
106 
107     RenderBlock::calcPrefWidths();
108 
109     m_maxPrefWidth = m_minPrefWidth;
110 }
111 
layout()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 overflowWidth and overflowHeight, since they act as a lower bound for docWidth() and docHeight().
137     setOverflowWidth(width());
138     setOverflowHeight(height());
139 
140     setOverflowWidth(docWidth());
141     setOverflowHeight(docHeight());
142 
143     ASSERT(layoutDelta() == IntSize());
144     ASSERT(m_layoutStateDisableCount == 0);
145     ASSERT(m_layoutState == &state);
146     m_layoutState = 0;
147     setNeedsLayout(false);
148 }
149 
mapLocalToContainer(RenderBoxModelObject * repaintContainer,bool fixed,bool,TransformState & transformState) const150 void RenderView::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool /*useTransforms*/, TransformState& transformState) const
151 {
152     // If a container was specified, and was not 0 or the RenderView,
153     // then we should have found it by now.
154     ASSERT_UNUSED(repaintContainer, !repaintContainer || repaintContainer == this);
155 
156     if (fixed && m_frameView)
157         transformState.move(m_frameView->scrollOffset());
158 }
159 
mapAbsoluteToLocalPoint(bool fixed,bool,TransformState & transformState) const160 void RenderView::mapAbsoluteToLocalPoint(bool fixed, bool /*useTransforms*/, TransformState& transformState) const
161 {
162     if (fixed && m_frameView)
163         transformState.move(-m_frameView->scrollOffset());
164 }
165 
paint(PaintInfo & paintInfo,int tx,int ty)166 void RenderView::paint(PaintInfo& paintInfo, int tx, int ty)
167 {
168     // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
169     ASSERT(!needsLayout());
170 
171     // Cache the print rect because the dirty rect could get changed during painting.
172     if (printing())
173         setPrintRect(paintInfo.rect);
174     else
175         setPrintRect(IntRect());
176     paintObject(paintInfo, tx, ty);
177 }
178 
rendererObscuresBackground(RenderObject * object)179 static inline bool rendererObscuresBackground(RenderObject* object)
180 {
181     return object && object->style()->visibility() == VISIBLE && object->style()->opacity() == 1 && !object->style()->hasTransform();
182 }
183 
paintBoxDecorations(PaintInfo & paintInfo,int,int)184 void RenderView::paintBoxDecorations(PaintInfo& paintInfo, int, int)
185 {
186     // Check to see if we are enclosed by a layer that requires complex painting rules.  If so, we cannot blit
187     // when scrolling, and we need to use slow repaints.  Examples of layers that require this are transparent layers,
188     // layers with reflections, or transformed layers.
189     // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being inside
190     // a transform, transparency layer, etc.
191     Element* elt;
192     for (elt = document()->ownerElement(); view() && elt && elt->renderer(); elt = elt->document()->ownerElement()) {
193         RenderLayer* layer = elt->renderer()->enclosingLayer();
194         if (layer->requiresSlowRepaints()) {
195             frameView()->setUseSlowRepaints();
196             break;
197         }
198     }
199 
200     // If painting will entirely fill the view, no need to fill the background.
201     if (elt || rendererObscuresBackground(firstChild()) || !view())
202         return;
203 
204     // This code typically only executes if the root element's visibility has been set to hidden,
205     // or there is a transform on the <html>.
206     // Only fill with the base background color (typically white) if we're the root document,
207     // since iframes/frames with no background in the child document should show the parent's background.
208     if (view()->isTransparent()) // FIXME: This needs to be dynamic.  We should be able to go back to blitting if we ever stop being transparent.
209         frameView()->setUseSlowRepaints(); // The parent must show behind the child.
210     else {
211         Color baseColor = frameView()->baseBackgroundColor();
212         if (baseColor.alpha() > 0) {
213             paintInfo.context->save();
214             paintInfo.context->setCompositeOperation(CompositeCopy);
215             paintInfo.context->fillRect(paintInfo.rect, baseColor);
216             paintInfo.context->restore();
217         } else
218             paintInfo.context->clearRect(paintInfo.rect);
219     }
220 }
221 
shouldRepaint(const IntRect & r) const222 bool RenderView::shouldRepaint(const IntRect& r) const
223 {
224     if (printing() || r.width() == 0 || r.height() == 0)
225         return false;
226 
227     if (!m_frameView)
228         return false;
229 
230     return true;
231 }
232 
repaintViewRectangle(const IntRect & ur,bool immediate)233 void RenderView::repaintViewRectangle(const IntRect& ur, bool immediate)
234 {
235     if (!shouldRepaint(ur))
236         return;
237 
238     // We always just invalidate the root view, since we could be an iframe that is clipped out
239     // or even invisible.
240     Element* elt = document()->ownerElement();
241     if (!elt)
242         m_frameView->repaintContentRectangle(ur, immediate);
243     else if (RenderBox* obj = elt->renderBox()) {
244         IntRect vr = viewRect();
245         IntRect r = intersection(ur, vr);
246 
247         // Subtract out the contentsX and contentsY offsets to get our coords within the viewing
248         // rectangle.
249         r.move(-vr.x(), -vr.y());
250 
251         // FIXME: Hardcoded offsets here are not good.
252         r.move(obj->borderLeft() + obj->paddingLeft(),
253                obj->borderTop() + obj->paddingTop());
254         obj->repaintRectangle(r, immediate);
255     }
256 }
257 
repaintRectangleInViewAndCompositedLayers(const IntRect & ur,bool immediate)258 void RenderView::repaintRectangleInViewAndCompositedLayers(const IntRect& ur, bool immediate)
259 {
260     if (!shouldRepaint(ur))
261         return;
262 
263     repaintViewRectangle(ur, immediate);
264 
265 #if USE(ACCELERATED_COMPOSITING)
266     // If we're a frame, repaintViewRectangle will have repainted via a RenderObject in the
267     // parent document.
268     if (document()->ownerElement())
269         return;
270 
271     if (compositor()->inCompositingMode())
272         compositor()->repaintCompositedLayersAbsoluteRect(ur);
273 #endif
274 }
275 
computeRectForRepaint(RenderBoxModelObject * repaintContainer,IntRect & rect,bool fixed)276 void RenderView::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed)
277 {
278     // If a container was specified, and was not 0 or the RenderView,
279     // then we should have found it by now.
280     ASSERT_UNUSED(repaintContainer, !repaintContainer || repaintContainer == this);
281 
282     if (printing())
283         return;
284 
285     if (fixed && m_frameView)
286         rect.move(m_frameView->scrollX(), m_frameView->scrollY());
287 
288     // Apply our transform if we have one (because of full page zooming).
289     if (m_layer && m_layer->transform())
290         rect = m_layer->transform()->mapRect(rect);
291 }
292 
absoluteRects(Vector<IntRect> & rects,int tx,int ty)293 void RenderView::absoluteRects(Vector<IntRect>& rects, int tx, int ty)
294 {
295     rects.append(IntRect(tx, ty, m_layer->width(), m_layer->height()));
296 }
297 
absoluteQuads(Vector<FloatQuad> & quads)298 void RenderView::absoluteQuads(Vector<FloatQuad>& quads)
299 {
300     quads.append(FloatRect(0, 0, m_layer->width(), m_layer->height()));
301 }
302 
rendererAfterPosition(RenderObject * object,unsigned offset)303 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)
304 {
305     if (!object)
306         return 0;
307 
308     RenderObject* child = object->childAt(offset);
309     return child ? child : object->nextInPreOrderAfterChildren();
310 }
311 
selectionBounds(bool clipToVisibleContent) const312 IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
313 {
314     document()->updateStyleIfNeeded();
315 
316     typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectionMap;
317     SelectionMap selectedObjects;
318 
319     RenderObject* os = m_selectionStart;
320     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
321     while (os && os != stop) {
322         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
323             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
324             selectedObjects.set(os, new RenderSelectionInfo(os, clipToVisibleContent));
325             RenderBlock* cb = os->containingBlock();
326             while (cb && !cb->isRenderView()) {
327                 RenderSelectionInfo* blockInfo = selectedObjects.get(cb);
328                 if (blockInfo)
329                     break;
330                 selectedObjects.set(cb, new RenderSelectionInfo(cb, clipToVisibleContent));
331                 cb = cb->containingBlock();
332             }
333         }
334 
335         os = os->nextInPreOrder();
336     }
337 
338     // Now create a single bounding box rect that encloses the whole selection.
339     IntRect selRect;
340     SelectionMap::iterator end = selectedObjects.end();
341     for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
342         RenderSelectionInfo* info = i->second;
343         selRect.unite(info->rect());
344         delete info;
345     }
346     return selRect;
347 }
348 
349 #if USE(ACCELERATED_COMPOSITING)
350 // Compositing layer dimensions take outline size into account, so we have to recompute layer
351 // bounds when it changes.
352 // FIXME: This is ugly; it would be nice to have a better way to do this.
setMaximalOutlineSize(int o)353 void RenderView::setMaximalOutlineSize(int o)
354 {
355     if (o != m_maximalOutlineSize) {
356         m_maximalOutlineSize = o;
357 
358         // maximalOutlineSize affects compositing layer dimensions.
359         compositor()->setCompositingLayersNeedRebuild();    // FIXME: this really just needs to be a geometry update.
360     }
361 }
362 #endif
363 
setSelection(RenderObject * start,int startPos,RenderObject * end,int endPos,SelectionRepaintMode blockRepaintMode)364 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
365 {
366     // Make sure both our start and end objects are defined.
367     // Check www.msnbc.com and try clicking around to find the case where this happened.
368     if ((start && !end) || (end && !start))
369         return;
370 
371     // Just return if the selection hasn't changed.
372     if (m_selectionStart == start && m_selectionStartPos == startPos &&
373         m_selectionEnd == end && m_selectionEndPos == endPos)
374         return;
375 
376     // Record the old selected objects.  These will be used later
377     // when we compare against the new selected objects.
378     int oldStartPos = m_selectionStartPos;
379     int oldEndPos = m_selectionEndPos;
380 
381     // Objects each have a single selection rect to examine.
382     typedef HashMap<RenderObject*, RenderSelectionInfo*> SelectedObjectMap;
383     SelectedObjectMap oldSelectedObjects;
384     SelectedObjectMap newSelectedObjects;
385 
386     // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
387     // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
388     // the union of those rects might remain the same even when changes have occurred.
389     typedef HashMap<RenderBlock*, RenderBlockSelectionInfo*> SelectedBlockMap;
390     SelectedBlockMap oldSelectedBlocks;
391     SelectedBlockMap newSelectedBlocks;
392 
393     RenderObject* os = m_selectionStart;
394     RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos);
395     while (os && os != stop) {
396         if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) {
397             // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
398             oldSelectedObjects.set(os, new RenderSelectionInfo(os, true));
399             RenderBlock* cb = os->containingBlock();
400             while (cb && !cb->isRenderView()) {
401                 RenderBlockSelectionInfo* blockInfo = oldSelectedBlocks.get(cb);
402                 if (blockInfo)
403                     break;
404                 oldSelectedBlocks.set(cb, new RenderBlockSelectionInfo(cb));
405                 cb = cb->containingBlock();
406             }
407         }
408 
409         os = os->nextInPreOrder();
410     }
411 
412     // Now clear the selection.
413     SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
414     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i)
415         i->first->setSelectionState(SelectionNone);
416 
417     // set selection start and end
418     m_selectionStart = start;
419     m_selectionStartPos = startPos;
420     m_selectionEnd = end;
421     m_selectionEndPos = endPos;
422 
423     // Update the selection status of all objects between m_selectionStart and m_selectionEnd
424     if (start && start == end)
425         start->setSelectionState(SelectionBoth);
426     else {
427         if (start)
428             start->setSelectionState(SelectionStart);
429         if (end)
430             end->setSelectionState(SelectionEnd);
431     }
432 
433     RenderObject* o = start;
434     stop = rendererAfterPosition(end, endPos);
435 
436     while (o && o != stop) {
437         if (o != start && o != end && o->canBeSelectionLeaf())
438             o->setSelectionState(SelectionInside);
439         o = o->nextInPreOrder();
440     }
441 
442     m_cachedSelectionBounds = IntRect();
443 
444     // Now that the selection state has been updated for the new objects, walk them again and
445     // put them in the new objects list.
446     o = start;
447     while (o && o != stop) {
448         if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) {
449             newSelectedObjects.set(o, new RenderSelectionInfo(o, true));
450             RenderBlock* cb = o->containingBlock();
451             while (cb && !cb->isRenderView()) {
452                 RenderBlockSelectionInfo* blockInfo = newSelectedBlocks.get(cb);
453                 if (blockInfo)
454                     break;
455                 blockInfo = new RenderBlockSelectionInfo(cb);
456                 newSelectedBlocks.set(cb, blockInfo);
457                 m_cachedSelectionBounds.unite(blockInfo->rects());
458                 cb = cb->containingBlock();
459             }
460         }
461 
462         o = o->nextInPreOrder();
463     }
464 
465     if (!m_frameView) {
466         // We built the maps, but we aren't going to use them.
467         // We need to delete the values, otherwise they'll all leak!
468         deleteAllValues(oldSelectedObjects);
469         deleteAllValues(newSelectedObjects);
470         deleteAllValues(oldSelectedBlocks);
471         deleteAllValues(newSelectedBlocks);
472         return;
473     }
474 
475     // Have any of the old selected objects changed compared to the new selection?
476     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
477         RenderObject* obj = i->first;
478         RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
479         RenderSelectionInfo* oldInfo = i->second;
480         if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state() ||
481             (m_selectionStart == obj && oldStartPos != m_selectionStartPos) ||
482             (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) {
483             oldInfo->repaint();
484             if (newInfo) {
485                 newInfo->repaint();
486                 newSelectedObjects.remove(obj);
487                 delete newInfo;
488             }
489         }
490         delete oldInfo;
491     }
492 
493     // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
494     SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
495     for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i) {
496         RenderSelectionInfo* newInfo = i->second;
497         newInfo->repaint();
498         delete newInfo;
499     }
500 
501     // Have any of the old blocks changed?
502     SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
503     for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
504         RenderBlock* block = i->first;
505         RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
506         RenderBlockSelectionInfo* oldInfo = i->second;
507         if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
508             if (blockRepaintMode == RepaintNewXOROld)
509                 oldInfo->repaint();
510             if (newInfo) {
511                 newInfo->repaint();
512                 newSelectedBlocks.remove(block);
513                 delete newInfo;
514             }
515         }
516         delete oldInfo;
517     }
518 
519     // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
520     SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
521     for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i) {
522         RenderBlockSelectionInfo* newInfo = i->second;
523         newInfo->repaint();
524         delete newInfo;
525     }
526 }
527 
clearSelection()528 void RenderView::clearSelection()
529 {
530     repaintViewRectangle(m_cachedSelectionBounds);
531     setSelection(0, -1, 0, -1, RepaintNewMinusOld);
532 }
533 
selectionStartEnd(int & startPos,int & endPos) const534 void RenderView::selectionStartEnd(int& startPos, int& endPos) const
535 {
536     startPos = m_selectionStartPos;
537     endPos = m_selectionEndPos;
538 }
539 
printing() const540 bool RenderView::printing() const
541 {
542     return document()->printing();
543 }
544 
updateWidgetPositions()545 void RenderView::updateWidgetPositions()
546 {
547     RenderWidgetSet::iterator end = m_widgets.end();
548     for (RenderWidgetSet::iterator it = m_widgets.begin(); it != end; ++it)
549         (*it)->updateWidgetPosition();
550 }
551 
addWidget(RenderWidget * o)552 void RenderView::addWidget(RenderWidget* o)
553 {
554     m_widgets.add(o);
555 }
556 
removeWidget(RenderWidget * o)557 void RenderView::removeWidget(RenderWidget* o)
558 {
559     m_widgets.remove(o);
560 }
561 
viewRect() const562 IntRect RenderView::viewRect() const
563 {
564     if (printing())
565         return IntRect(0, 0, width(), height());
566     if (m_frameView)
567         return m_frameView->visibleContentRect();
568     return IntRect();
569 }
570 
docHeight() const571 int RenderView::docHeight() const
572 {
573     int h = lowestPosition();
574 
575     // FIXME: This doesn't do any margin collapsing.
576     // Instead of this dh computation we should keep the result
577     // when we call RenderBlock::layout.
578     int dh = 0;
579     for (RenderBox* c = firstChildBox(); c; c = c->nextSiblingBox())
580         dh += c->height() + c->marginTop() + c->marginBottom();
581 
582     if (dh > h)
583         h = dh;
584 
585     return h;
586 }
587 
docWidth() const588 int RenderView::docWidth() const
589 {
590     int w = rightmostPosition();
591 
592     for (RenderBox* c = firstChildBox(); c; c = c->nextSiblingBox()) {
593         int dw = c->width() + c->marginLeft() + c->marginRight();
594         if (dw > w)
595             w = dw;
596     }
597 
598     return w;
599 }
600 
viewHeight() const601 int RenderView::viewHeight() const
602 {
603     int height = 0;
604     if (!printing() && m_frameView) {
605         height = m_frameView->layoutHeight();
606         height = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(height)) : height;
607     }
608     return height;
609 }
610 
viewWidth() const611 int RenderView::viewWidth() const
612 {
613     int width = 0;
614     if (!printing() && m_frameView) {
615         width = m_frameView->layoutWidth();
616         width = m_frameView->useFixedLayout() ? ceilf(style()->effectiveZoom() * float(width)) : width;
617     }
618     return width;
619 }
620 
zoomFactor() const621 float RenderView::zoomFactor() const
622 {
623     if (m_frameView->frame() && m_frameView->frame()->shouldApplyPageZoom())
624         return m_frameView->frame()->zoomFactor();
625 
626     return 1.0f;
627 }
628 
629 // The idea here is to take into account what object is moving the pagination point, and
630 // thus choose the best place to chop it.
setBestTruncatedAt(int y,RenderBoxModelObject * forRenderer,bool forcedBreak)631 void RenderView::setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak)
632 {
633     // Nobody else can set a page break once we have a forced break.
634     if (m_forcedPageBreak)
635         return;
636 
637     // Forced breaks always win over unforced breaks.
638     if (forcedBreak) {
639         m_forcedPageBreak = true;
640         m_bestTruncatedAt = y;
641         return;
642     }
643 
644     // Prefer the widest object that tries to move the pagination point
645     IntRect boundingBox = forRenderer->borderBoundingBox();
646     if (boundingBox.width() > m_truncatorWidth) {
647         m_truncatorWidth = boundingBox.width();
648         m_bestTruncatedAt = y;
649     }
650 }
651 
pushLayoutState(RenderObject * root)652 void RenderView::pushLayoutState(RenderObject* root)
653 {
654     ASSERT(!doingFullRepaint());
655     ASSERT(m_layoutStateDisableCount == 0);
656     ASSERT(m_layoutState == 0);
657 
658     m_layoutState = new (renderArena()) LayoutState(root);
659 }
660 
updateHitTestResult(HitTestResult & result,const IntPoint & point)661 void RenderView::updateHitTestResult(HitTestResult& result, const IntPoint& point)
662 {
663     if (result.innerNode())
664         return;
665 
666     Node* node = document()->documentElement();
667     if (node) {
668         result.setInnerNode(node);
669         if (!result.innerNonSharedNode())
670             result.setInnerNonSharedNode(node);
671         result.setLocalPoint(point);
672     }
673 }
674 
675 #if USE(ACCELERATED_COMPOSITING)
usesCompositing() const676 bool RenderView::usesCompositing() const
677 {
678     return m_compositor && m_compositor->inCompositingMode();
679 }
680 
compositor()681 RenderLayerCompositor* RenderView::compositor()
682 {
683     if (!m_compositor)
684         m_compositor.set(new RenderLayerCompositor(this));
685 
686     return m_compositor.get();
687 }
688 #endif
689 
didMoveOnscreen()690 void RenderView::didMoveOnscreen()
691 {
692 #if USE(ACCELERATED_COMPOSITING)
693     if (m_compositor)
694         m_compositor->didMoveOnscreen();
695 #endif
696 }
697 
willMoveOffscreen()698 void RenderView::willMoveOffscreen()
699 {
700 #if USE(ACCELERATED_COMPOSITING)
701     if (m_compositor)
702         m_compositor->willMoveOffscreen();
703 #endif
704 }
705 
706 } // namespace WebCore
707