1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@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 "FrameView.h"
26#include "LayoutState.h"
27#include "RenderBlock.h"
28#include <wtf/OwnPtr.h>
29
30namespace WebCore {
31
32class RenderWidget;
33
34#if USE(ACCELERATED_COMPOSITING)
35class RenderLayerCompositor;
36#endif
37
38class RenderView : public RenderBlock {
39public:
40    RenderView(Node*, FrameView*);
41    virtual ~RenderView();
42
43    virtual const char* renderName() const { return "RenderView"; }
44
45    virtual bool isRenderView() const { return true; }
46
47    virtual void layout();
48    virtual void calcWidth();
49    virtual void calcHeight();
50    virtual void calcPrefWidths();
51
52    // The same as the FrameView's layoutHeight/layoutWidth but with null check guards.
53    int viewHeight() const;
54    int viewWidth() const;
55
56    float zoomFactor() const;
57
58    FrameView* frameView() const { return m_frameView; }
59
60    virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
61    virtual void repaintViewRectangle(const IntRect&, bool immediate = false);
62    // Repaint the view, and all composited layers that intersect the given absolute rectangle.
63    // FIXME: ideally we'd never have to do this, if all repaints are container-relative.
64    virtual void repaintRectangleInViewAndCompositedLayers(const IntRect&, bool immediate = false);
65
66    virtual void paint(PaintInfo&, int tx, int ty);
67    virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
68
69    enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld };
70    void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld);
71    void clearSelection();
72    virtual RenderObject* selectionStart() const { return m_selectionStart; }
73    virtual RenderObject* selectionEnd() const { return m_selectionEnd; }
74
75    bool printing() const;
76    void setPrintImages(bool enable) { m_printImages = enable; }
77    bool printImages() const { return m_printImages; }
78    void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_minimumColumnHeight = 0; m_forcedPageBreak = false; }
79    void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
80    void setMinimumColumnHeight(int height) { m_minimumColumnHeight = height; }
81    int bestTruncatedAt() const { return m_bestTruncatedAt; }
82    int minimumColumnHeight() const { return m_minimumColumnHeight; }
83
84    int truncatedAt() const { return m_truncatedAt; }
85
86    virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
87    virtual void absoluteQuads(Vector<FloatQuad>&);
88
89    IntRect selectionBounds(bool clipToVisibleContent = true) const;
90
91#if USE(ACCELERATED_COMPOSITING)
92    void setMaximalOutlineSize(int o);
93#else
94    void setMaximalOutlineSize(int o) { m_maximalOutlineSize = o; }
95#endif
96    int maximalOutlineSize() const { return m_maximalOutlineSize; }
97
98    virtual IntRect viewRect() const;
99
100    void selectionStartEnd(int& startPos, int& endPos) const;
101
102    IntRect printRect() const { return m_printRect; }
103    void setPrintRect(const IntRect& r) { m_printRect = r; }
104
105    void updateWidgetPositions();
106    void addWidget(RenderWidget*);
107    void removeWidget(RenderWidget*);
108#ifdef ANDROID_PLUGINS
109    const HashSet<RenderWidget*>& widgets() const { return m_widgets; }
110#endif
111
112    // layoutDelta is used transiently during layout to store how far an object has moved from its
113    // last layout location, in order to repaint correctly.
114    // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter.
115    IntSize layoutDelta() const
116    {
117        return m_layoutState ? m_layoutState->m_layoutDelta : IntSize();
118    }
119    void addLayoutDelta(const IntSize& delta)
120    {
121        if (m_layoutState)
122            m_layoutState->m_layoutDelta += delta;
123    }
124
125    bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); }
126
127    void pushLayoutState(RenderBox* renderer, const IntSize& offset)
128    {
129        if (doingFullRepaint())
130            return;
131        // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
132        m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset);
133    }
134
135    void pushLayoutState(RenderObject*);
136
137    void popLayoutState()
138    {
139        if (doingFullRepaint())
140            return;
141        LayoutState* state = m_layoutState;
142        m_layoutState = state->m_next;
143        state->destroy(renderArena());
144    }
145
146    bool shouldDisableLayoutStateForSubtree(RenderObject*) const;
147
148    // Returns true if layoutState should be used for its cached offset and clip.
149    bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m_layoutState; }
150    LayoutState* layoutState() const { return m_layoutState; }
151
152    // Suspends the LayoutState optimization. Used under transforms that cannot be represented by
153    // LayoutState (common in SVG) and when manipulating the render tree during layout in ways
154    // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around).
155    // Note that even when disabled, LayoutState is still used to store layoutDelta.
156    void disableLayoutState() { m_layoutStateDisableCount++; }
157    void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; }
158
159    virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
160
161    // Notifications that this view became visible in a window, or will be
162    // removed from the window.
163    void didMoveOnscreen();
164    void willMoveOffscreen();
165
166#if USE(ACCELERATED_COMPOSITING)
167    RenderLayerCompositor* compositor();
168    bool usesCompositing() const;
169#endif
170
171protected:
172    virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
173    virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
174
175private:
176    bool shouldRepaint(const IntRect& r) const;
177
178#ifdef FLATTEN_FRAMESET
179public: // used by layout function
180#endif
181    int docHeight() const;
182    int docWidth() const;
183
184protected:
185    FrameView* m_frameView;
186
187    RenderObject* m_selectionStart;
188    RenderObject* m_selectionEnd;
189    int m_selectionStartPos;
190    int m_selectionEndPos;
191
192    // used to ignore viewport width when printing to the printer
193    bool m_printImages;
194    int m_truncatedAt;
195
196    int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
197    IntRect m_printRect; // Used when printing.
198
199    typedef HashSet<RenderWidget*> RenderWidgetSet;
200
201    RenderWidgetSet m_widgets;
202
203private:
204    int m_bestTruncatedAt;
205    int m_truncatorWidth;
206    int m_minimumColumnHeight;
207    bool m_forcedPageBreak;
208    LayoutState* m_layoutState;
209    unsigned m_layoutStateDisableCount;
210#if USE(ACCELERATED_COMPOSITING)
211    OwnPtr<RenderLayerCompositor> m_compositor;
212#endif
213};
214
215inline RenderView* toRenderView(RenderObject* object)
216{
217    ASSERT(!object || object->isRenderView());
218    return static_cast<RenderView*>(object);
219}
220
221inline const RenderView* toRenderView(const RenderObject* object)
222{
223    ASSERT(!object || object->isRenderView());
224    return static_cast<const RenderView*>(object);
225}
226
227// This will catch anyone doing an unnecessary cast.
228void toRenderView(const RenderView*);
229
230
231// Stack-based class to assist with LayoutState push/pop
232class LayoutStateMaintainer : public Noncopyable {
233public:
234    // ctor to push now
235    LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool disableState = false)
236        : m_view(view)
237        , m_disabled(disableState)
238        , m_didStart(false)
239        , m_didEnd(false)
240    {
241        push(root, offset);
242    }
243
244    // ctor to maybe push later
245    LayoutStateMaintainer(RenderView* view)
246        : m_view(view)
247        , m_disabled(false)
248        , m_didStart(false)
249        , m_didEnd(false)
250    {
251    }
252
253    ~LayoutStateMaintainer()
254    {
255        ASSERT(m_didStart == m_didEnd);   // if this fires, it means that someone did a push(), but forgot to pop().
256    }
257
258    void push(RenderBox* root, IntSize offset)
259    {
260        ASSERT(!m_didStart);
261        // We push state even if disabled, because we still need to store layoutDelta
262        m_view->pushLayoutState(root, offset);
263        if (m_disabled)
264            m_view->disableLayoutState();
265        m_didStart = true;
266    }
267
268    void pop()
269    {
270        if (m_didStart) {
271            ASSERT(!m_didEnd);
272            m_view->popLayoutState();
273            if (m_disabled)
274                m_view->enableLayoutState();
275            m_didEnd = true;
276        }
277    }
278
279    bool didPush() const { return m_didStart; }
280
281private:
282    RenderView* m_view;
283    bool m_disabled : 1;        // true if the offset and clip part of layoutState is disabled
284    bool m_didStart : 1;        // true if we did a push or disable
285    bool m_didEnd : 1;          // true if we popped or re-enabled
286};
287
288} // namespace WebCore
289
290#endif // RenderView_h
291