Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  * Copyright (C) 2006 Apple Computer, Inc.
      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 
     22 #ifndef RenderView_h
     23 #define RenderView_h
     24 
     25 #include "core/frame/FrameView.h"
     26 #include "core/rendering/LayoutState.h"
     27 #include "core/rendering/RenderBlockFlow.h"
     28 #include "platform/PODFreeListArena.h"
     29 #include "platform/scroll/ScrollableArea.h"
     30 #include "wtf/OwnPtr.h"
     31 
     32 namespace WebCore {
     33 
     34 class FlowThreadController;
     35 class RenderLayerCompositor;
     36 class RenderQuote;
     37 
     38 // The root of the render tree, corresponding to the CSS initial containing block.
     39 // It's dimensions match that of the logical viewport (which may be different from
     40 // the visible viewport in fixed-layout mode), and it is always at position (0,0)
     41 // relative to the document (and so isn't necessarily in view).
     42 class RenderView FINAL : public RenderBlockFlow {
     43 public:
     44     explicit RenderView(Document*);
     45     virtual ~RenderView();
     46 
     47     bool hitTest(const HitTestRequest&, HitTestResult&);
     48     bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&);
     49 
     50     virtual const char* renderName() const OVERRIDE { return "RenderView"; }
     51 
     52     virtual bool isRenderView() const OVERRIDE { return true; }
     53 
     54     virtual LayerType layerTypeRequired() const OVERRIDE { return NormalLayer; }
     55 
     56     virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
     57 
     58     virtual void layout() OVERRIDE;
     59     virtual void updateLogicalWidth() OVERRIDE;
     60     virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
     61 
     62     virtual LayoutUnit availableLogicalHeight(AvailableLogicalHeightType) const OVERRIDE;
     63 
     64     // The same as the FrameView's layoutHeight/layoutWidth but with null check guards.
     65     int viewHeight(IncludeScrollbarsInRect = ExcludeScrollbars) const;
     66     int viewWidth(IncludeScrollbarsInRect = ExcludeScrollbars) const;
     67     int viewLogicalWidth() const
     68     {
     69         return style()->isHorizontalWritingMode() ? viewWidth(ExcludeScrollbars) : viewHeight(ExcludeScrollbars);
     70     }
     71     int viewLogicalHeight() const;
     72     LayoutUnit viewLogicalHeightForPercentages() const;
     73 
     74     float zoomFactor() const;
     75 
     76     FrameView* frameView() const { return m_frameView; }
     77 
     78     virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
     79     void repaintViewRectangle(const LayoutRect&) const;
     80 
     81     void repaintViewAndCompositedLayers();
     82 
     83     virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
     84     virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE;
     85 
     86     enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld, RepaintNothing };
     87     void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld);
     88     void getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const;
     89     void clearSelection();
     90     RenderObject* selectionStart() const { return m_selectionStart; }
     91     RenderObject* selectionEnd() const { return m_selectionEnd; }
     92     IntRect selectionBounds(bool clipToVisibleContent = true) const;
     93     void selectionStartEnd(int& startPos, int& endPos) const;
     94     void repaintSelection() const;
     95 
     96     virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE;
     97     virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE;
     98 
     99     virtual LayoutRect viewRect() const OVERRIDE;
    100 
    101     // layoutDelta is used transiently during layout to store how far an object has moved from its
    102     // last layout location, in order to repaint correctly.
    103     // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter.
    104     LayoutSize layoutDelta() const
    105     {
    106         ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
    107         return m_layoutState ? m_layoutState->layoutDelta() : LayoutSize();
    108     }
    109     void addLayoutDelta(const LayoutSize& delta)
    110     {
    111         ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
    112         if (m_layoutState)
    113             m_layoutState->addLayoutDelta(delta);
    114     }
    115 
    116 #if ASSERT_ENABLED
    117     bool layoutDeltaMatches(const LayoutSize& delta)
    118     {
    119         ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
    120         if (!m_layoutState)
    121             return false;
    122         return (delta.width() == m_layoutState->layoutDelta().width() || m_layoutState->layoutDeltaXSaturated()) && (delta.height() == m_layoutState->layoutDelta().height() || m_layoutState->layoutDeltaYSaturated());
    123     }
    124 #endif
    125 
    126     bool shouldDoFullRepaintForNextLayout() const;
    127     bool doingFullRepaint() const { return m_frameView->needsFullPaintInvalidation(); }
    128 
    129     // Returns true if layoutState should be used for its cached offset and clip.
    130     bool layoutStateCachedOffsetsEnabled() const { return m_layoutState && m_layoutState->cachedOffsetsEnabled(); }
    131     LayoutState* layoutState() const { return m_layoutState; }
    132 
    133     bool canMapUsingLayoutStateForContainer(const RenderObject* repaintContainer) const
    134     {
    135         // FIXME: LayoutState should be enabled for other repaint containers than the RenderView. crbug.com/363834
    136         return layoutStateCachedOffsetsEnabled() && (repaintContainer == this);
    137     }
    138 
    139     virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRIDE;
    140 
    141     LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; }
    142     void setPageLogicalHeight(LayoutUnit height)
    143     {
    144         if (m_pageLogicalHeight != height) {
    145             m_pageLogicalHeight = height;
    146             m_pageLogicalHeightChanged = true;
    147         }
    148     }
    149     bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
    150 
    151     // Notification that this view moved into or out of a native window.
    152     void setIsInWindow(bool);
    153 
    154     RenderLayerCompositor* compositor();
    155     bool usesCompositing() const;
    156 
    157     IntRect unscaledDocumentRect() const;
    158     LayoutRect backgroundRect(RenderBox* backgroundRenderer) const;
    159 
    160     IntRect documentRect() const;
    161 
    162     // Renderer that paints the root background has background-images which all have background-attachment: fixed.
    163     bool rootBackgroundIsEntirelyFixed() const;
    164 
    165     FlowThreadController* flowThreadController();
    166 
    167     IntervalArena* intervalArena();
    168 
    169     void setRenderQuoteHead(RenderQuote* head) { m_renderQuoteHead = head; }
    170     RenderQuote* renderQuoteHead() const { return m_renderQuoteHead; }
    171 
    172     // FIXME: This is a work around because the current implementation of counters
    173     // requires walking the entire tree repeatedly and most pages don't actually use either
    174     // feature so we shouldn't take the performance hit when not needed. Long term we should
    175     // rewrite the counter and quotes code.
    176     void addRenderCounter() { m_renderCounterCount++; }
    177     void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCounterCount--; }
    178     bool hasRenderCounters() { return m_renderCounterCount; }
    179 
    180     virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const OVERRIDE;
    181 
    182     double layoutViewportWidth() const;
    183     double layoutViewportHeight() const;
    184 
    185     void pushLayoutState(LayoutState&);
    186     void popLayoutState();
    187 private:
    188     virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
    189     virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
    190     virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE;
    191     virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE;
    192 
    193     virtual void invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer) OVERRIDE FINAL;
    194 
    195     bool shouldRepaint(const LayoutRect&) const;
    196 
    197     bool rootFillsViewportBackground(RenderBox* rootBox) const;
    198 
    199     void layoutContent();
    200 #ifndef NDEBUG
    201     void checkLayoutState();
    202 #endif
    203 
    204     void positionDialog(RenderBox*);
    205     void positionDialogs();
    206 
    207     friend class ForceHorriblySlowRectMapping;
    208 
    209     bool shouldUsePrintingLayout() const;
    210 
    211     RenderObject* backgroundRenderer() const;
    212 
    213     FrameView* m_frameView;
    214 
    215     RenderObject* m_selectionStart;
    216     RenderObject* m_selectionEnd;
    217 
    218     int m_selectionStartPos;
    219     int m_selectionEndPos;
    220 
    221     LayoutUnit m_pageLogicalHeight;
    222     bool m_pageLogicalHeightChanged;
    223     LayoutState* m_layoutState;
    224     OwnPtr<RenderLayerCompositor> m_compositor;
    225     OwnPtr<FlowThreadController> m_flowThreadController;
    226     RefPtr<IntervalArena> m_intervalArena;
    227 
    228     RenderQuote* m_renderQuoteHead;
    229     unsigned m_renderCounterCount;
    230 };
    231 
    232 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView());
    233 
    234 // Suspends the LayoutState cached offset and clipRect optimization. Used under transforms
    235 // that cannot be represented by LayoutState (common in SVG) and when manipulating the render
    236 // tree during layout in ways that can trigger repaint of a non-child (e.g. when a list item
    237 // moves its list marker around). Note that even when disabled, LayoutState is still used to
    238 // store layoutDelta.
    239 class ForceHorriblySlowRectMapping {
    240     WTF_MAKE_NONCOPYABLE(ForceHorriblySlowRectMapping);
    241 public:
    242     ForceHorriblySlowRectMapping(const RenderObject& root)
    243         : m_view(*root.view())
    244         , m_didDisable(m_view.layoutState() && m_view.layoutState()->cachedOffsetsEnabled())
    245     {
    246         if (m_view.layoutState())
    247             m_view.layoutState()->m_cachedOffsetsEnabled = false;
    248 #if ASSERT_ENABLED
    249         m_layoutState = m_view.layoutState();
    250 #endif
    251     }
    252 
    253     ~ForceHorriblySlowRectMapping()
    254     {
    255         ASSERT(m_view.layoutState() == m_layoutState);
    256         if (m_didDisable)
    257             m_view.layoutState()->m_cachedOffsetsEnabled = true;
    258     }
    259 private:
    260     RenderView& m_view;
    261     bool m_didDisable;
    262 #if ASSERT_ENABLED
    263     LayoutState* m_layoutState;
    264 #endif
    265 };
    266 
    267 } // namespace WebCore
    268 
    269 #endif // RenderView_h
    270