Fix the issue that Web Audio test case fails on PR3.
[framework/web/webkit-efl.git] / Source / WebCore / rendering / RenderView.h
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 "PODFreeListArena.h"
28 #include "RenderBlock.h"
29 #include <wtf/OwnPtr.h>
30
31 namespace WebCore {
32
33 class FlowThreadController;
34 class RenderWidget;
35
36 #if USE(ACCELERATED_COMPOSITING)
37 class RenderLayerCompositor;
38 #endif
39
40 #if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
41 class CustomFilterGlobalContext;
42 #endif
43
44 class RenderView : public RenderBlock {
45 public:
46     RenderView(Node*, FrameView*);
47     virtual ~RenderView();
48
49     bool hitTest(const HitTestRequest&, HitTestResult&);
50
51     virtual const char* renderName() const OVERRIDE { return "RenderView"; }
52
53     virtual bool isRenderView() const OVERRIDE { return true; }
54
55     virtual bool requiresLayer() const OVERRIDE { return true; }
56
57     virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
58
59     virtual void layout() OVERRIDE;
60     virtual void computeLogicalWidth() OVERRIDE;
61     virtual void computeLogicalHeight() OVERRIDE;
62     // FIXME: This override is not needed and should be removed
63     // it only exists to make computePreferredLogicalWidths public.
64     virtual void computePreferredLogicalWidths() OVERRIDE;
65
66     virtual LayoutUnit availableLogicalHeight() const OVERRIDE;
67
68     // The same as the FrameView's layoutHeight/layoutWidth but with null check guards.
69     int viewHeight() const;
70     int viewWidth() const;
71     int viewLogicalWidth() const { return style()->isHorizontalWritingMode() ? viewWidth() : viewHeight(); }
72     int viewLogicalHeight() const;
73
74     float zoomFactor() const;
75
76     FrameView* frameView() const { return m_frameView; }
77
78     virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect&, bool fixed = false) const;
79     virtual void repaintViewRectangle(const LayoutRect&, bool immediate = false);
80     // Repaint the view, and all composited layers that intersect the given absolute rectangle.
81     // FIXME: ideally we'd never have to do this, if all repaints are container-relative.
82     virtual void repaintRectangleInViewAndCompositedLayers(const LayoutRect&, bool immediate = false);
83
84     virtual void paint(PaintInfo&, const LayoutPoint&);
85     virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE;
86
87     enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld, RepaintNothing };
88     void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld);
89     void getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const;
90     void clearSelection();
91     RenderObject* selectionStart() const { return m_selectionStart; }
92     RenderObject* selectionEnd() const { return m_selectionEnd; }
93     IntRect selectionBounds(bool clipToVisibleContent = true) const;
94     void selectionStartEnd(int& startPos, int& endPos) const;
95
96     bool printing() const;
97
98     virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
99     virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
100
101 #if USE(ACCELERATED_COMPOSITING)
102     void setMaximalOutlineSize(int o);
103 #else
104     void setMaximalOutlineSize(int o) { m_maximalOutlineSize = o; }
105 #endif
106     int maximalOutlineSize() const { return m_maximalOutlineSize; }
107
108     virtual LayoutRect viewRect() const OVERRIDE;
109
110     void updateWidgetPositions();
111     void addWidget(RenderWidget*);
112     void removeWidget(RenderWidget*);
113     
114     void notifyWidgets(WidgetNotification);
115
116     // layoutDelta is used transiently during layout to store how far an object has moved from its
117     // last layout location, in order to repaint correctly.
118     // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter.
119     LayoutSize layoutDelta() const
120     {
121         return m_layoutState ? m_layoutState->m_layoutDelta : LayoutSize();
122     }
123     void addLayoutDelta(const LayoutSize& delta) 
124     {
125         if (m_layoutState)
126             m_layoutState->m_layoutDelta += delta;
127     }
128
129     bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); }
130
131     // Subtree push/pop
132     void pushLayoutState(RenderObject*);
133     void popLayoutState(RenderObject*) { return popLayoutState(); } // Just doing this to keep popLayoutState() private and to make the subtree calls symmetrical.
134
135     bool shouldDisableLayoutStateForSubtree(RenderObject*) const;
136
137     // Returns true if layoutState should be used for its cached offset and clip.
138     bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m_layoutState; }
139     LayoutState* layoutState() const { return m_layoutState; }
140
141     virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
142
143     unsigned pageLogicalHeight() const { return m_pageLogicalHeight; }
144     void setPageLogicalHeight(unsigned height)
145     {
146         if (m_pageLogicalHeight != height) {
147             m_pageLogicalHeight = height;
148             m_pageLogicalHeightChanged = true;
149         }
150     }
151
152     // FIXME: These functions are deprecated. No code should be added that uses these.
153     int bestTruncatedAt() const { return m_legacyPrinting.m_bestTruncatedAt; }
154     void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
155     int truncatedAt() const { return m_legacyPrinting.m_truncatedAt; }
156     void setTruncatedAt(int y)
157     { 
158         m_legacyPrinting.m_truncatedAt = y;
159         m_legacyPrinting.m_bestTruncatedAt = 0;
160         m_legacyPrinting.m_truncatorWidth = 0;
161         m_legacyPrinting.m_forcedPageBreak = false;
162     }
163     const IntRect& printRect() const { return m_legacyPrinting.m_printRect; }
164     void setPrintRect(const IntRect& r) { m_legacyPrinting.m_printRect = r; }
165     // End deprecated functions.
166
167     // Notifications that this view became visible in a window, or will be
168     // removed from the window.
169     void didMoveOnscreen();
170     void willMoveOffscreen();
171
172 #if USE(ACCELERATED_COMPOSITING)
173     RenderLayerCompositor* compositor();
174     bool usesCompositing() const;
175 #endif
176
177 #if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
178     CustomFilterGlobalContext* customFilterGlobalContext();
179 #endif
180
181     IntRect unscaledDocumentRect() const;
182     LayoutRect backgroundRect(RenderBox* backgroundRenderer) const;
183
184     IntRect documentRect() const;
185
186     bool hasRenderNamedFlowThreads() const;
187     FlowThreadController* flowThreadController();
188
189     void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
190
191     IntervalArena* intervalArena();
192
193     IntSize viewportSize() const { return document()->viewportSize(); }
194
195     void setFixedPositionedObjectsNeedLayout();
196
197     // FIXME: This is a work around because the current implementation of counters and quotes
198     // requires walking the entire tree repeatedly and most pages don't actually use either
199     // feature so we shouldn't take the performance hit when not needed. Long term we should
200     // rewrite the counter and quotes code.
201     void addRenderQuote() { m_renderQuoteCount++; }
202     void removeRenderQuote() { ASSERT(m_renderQuoteCount > 0); m_renderQuoteCount--; }
203     bool hasRenderQuotes() { return m_renderQuoteCount; }
204     void addRenderCounter() { m_renderCounterCount++; }
205     void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCounterCount--; }
206     bool hasRenderCounters() { return m_renderCounterCount; }
207
208 protected:
209     virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&, ApplyContainerFlipOrNot = ApplyContainerFlip, bool* wasFixed = 0) const;
210     virtual const RenderObject* pushMappingToContainer(const RenderBoxModelObject* ancestorToStopAt, RenderGeometryMap&) const;
211     virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
212     virtual bool requiresColumns(int desiredColumnCount) const OVERRIDE;
213
214 private:
215     virtual void calcColumnWidth() OVERRIDE;
216     virtual ColumnInfo::PaginationUnit paginationUnit() const OVERRIDE;
217
218     bool shouldRepaint(const LayoutRect&) const;
219
220     // These functions may only be accessed by LayoutStateMaintainer.
221     void pushLayoutState(RenderFlowThread*, bool regionsChanged);
222     bool pushLayoutState(RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
223     {
224         // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
225         if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer->hasColumns() || renderer->inRenderFlowThread()
226             || m_layoutState->lineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isBlockFlow())) {
227             m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo);
228             return true;
229         }
230         return false;
231     }
232
233     void popLayoutState()
234     {
235         LayoutState* state = m_layoutState;
236         m_layoutState = state->m_next;
237         state->destroy(renderArena());
238     }
239
240     // Suspends the LayoutState optimization. Used under transforms that cannot be represented by
241     // LayoutState (common in SVG) and when manipulating the render tree during layout in ways
242     // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around).
243     // Note that even when disabled, LayoutState is still used to store layoutDelta.
244     // These functions may only be accessed by LayoutStateMaintainer or LayoutStateDisabler.
245     void disableLayoutState() { m_layoutStateDisableCount++; }
246     void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; }
247
248     size_t getRetainedWidgets(Vector<RenderWidget*>&);
249     void releaseWidgets(Vector<RenderWidget*>&);
250     
251     friend class LayoutStateMaintainer;
252     friend class LayoutStateDisabler;
253
254 protected:
255     FrameView* m_frameView;
256
257     RenderObject* m_selectionStart;
258     RenderObject* m_selectionEnd;
259     int m_selectionStartPos;
260     int m_selectionEndPos;
261
262     // FIXME: Only used by embedded WebViews inside AppKit NSViews.  Find a way to remove.
263     struct LegacyPrinting {
264         LegacyPrinting()
265             : m_bestTruncatedAt(0)
266             , m_truncatedAt(0)
267             , m_truncatorWidth(0)
268             , m_forcedPageBreak(false)
269         { }
270
271         int m_bestTruncatedAt;
272         int m_truncatedAt;
273         int m_truncatorWidth;
274         IntRect m_printRect;
275         bool m_forcedPageBreak;
276     };
277     LegacyPrinting m_legacyPrinting;
278     // End deprecated members.
279
280     int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
281
282     typedef HashSet<RenderWidget*> RenderWidgetSet;
283     RenderWidgetSet m_widgets;
284
285     typedef HashSet<RenderBox*> RenderBoxSet;
286     OwnPtr<RenderBoxSet> m_fixedPositionedElements;
287
288 private:
289     bool shouldUsePrintingLayout() const;
290
291     unsigned m_pageLogicalHeight;
292     bool m_pageLogicalHeightChanged;
293     LayoutState* m_layoutState;
294     unsigned m_layoutStateDisableCount;
295 #if USE(ACCELERATED_COMPOSITING)
296     OwnPtr<RenderLayerCompositor> m_compositor;
297 #endif
298 #if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
299     OwnPtr<CustomFilterGlobalContext> m_customFilterGlobalContext;
300 #endif
301     OwnPtr<FlowThreadController> m_flowThreadController;
302     RefPtr<IntervalArena> m_intervalArena;
303
304     unsigned m_renderQuoteCount;
305     unsigned m_renderCounterCount;
306 };
307
308 inline RenderView* toRenderView(RenderObject* object)
309 {
310     ASSERT(!object || object->isRenderView());
311     return static_cast<RenderView*>(object);
312 }
313
314 inline const RenderView* toRenderView(const RenderObject* object)
315 {
316     ASSERT(!object || object->isRenderView());
317     return static_cast<const RenderView*>(object);
318 }
319
320 // This will catch anyone doing an unnecessary cast.
321 void toRenderView(const RenderView*);
322
323
324 ALWAYS_INLINE RenderView* RenderObject::view() const
325 {
326     return toRenderView(document()->renderer());
327 }
328
329 // Stack-based class to assist with LayoutState push/pop
330 class LayoutStateMaintainer {
331     WTF_MAKE_NONCOPYABLE(LayoutStateMaintainer);
332 public:
333     // ctor to push now
334     LayoutStateMaintainer(RenderView* view, RenderBox* root, LayoutSize offset, bool disableState = false, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
335         : m_view(view)
336         , m_disabled(disableState)
337         , m_didStart(false)
338         , m_didEnd(false)
339         , m_didCreateLayoutState(false)
340     {
341         push(root, offset, pageHeight, pageHeightChanged, colInfo);
342     }
343     
344     // ctor to maybe push later
345     LayoutStateMaintainer(RenderView* view)
346         : m_view(view)
347         , m_disabled(false)
348         , m_didStart(false)
349         , m_didEnd(false)
350         , m_didCreateLayoutState(false)
351     {
352     }
353     
354     LayoutStateMaintainer(RenderView* view, RenderFlowThread* flowThread, bool regionsChanged)
355         : m_view(view)
356         , m_disabled(false)
357         , m_didStart(false)
358         , m_didEnd(false)
359         , m_didCreateLayoutState(false)
360     {
361         push(flowThread, regionsChanged);
362     }
363     
364     ~LayoutStateMaintainer()
365     {
366         ASSERT(m_didStart == m_didEnd);   // if this fires, it means that someone did a push(), but forgot to pop().
367     }
368
369     void push(RenderBox* root, LayoutSize offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
370     {
371         ASSERT(!m_didStart);
372         // We push state even if disabled, because we still need to store layoutDelta
373         m_didCreateLayoutState = m_view->pushLayoutState(root, offset, pageHeight, pageHeightChanged, colInfo);
374         if (m_disabled && m_didCreateLayoutState)
375             m_view->disableLayoutState();
376         m_didStart = true;
377     }
378     
379     void push(RenderFlowThread* flowThread, bool regionsChanged)
380     {
381         ASSERT(!m_didStart);
382         m_view->pushLayoutState(flowThread, regionsChanged);
383         m_didCreateLayoutState = true;
384         m_didStart = true;
385     }
386
387     void pop()
388     {
389         if (m_didStart) {
390             ASSERT(!m_didEnd);
391             if (m_didCreateLayoutState) {
392                 m_view->popLayoutState();
393                 if (m_disabled)
394                     m_view->enableLayoutState();
395             }
396             
397             m_didEnd = true;
398         }
399     }
400
401     bool didPush() const { return m_didStart; }
402
403 private:
404     RenderView* m_view;
405     bool m_disabled : 1;        // true if the offset and clip part of layoutState is disabled
406     bool m_didStart : 1;        // true if we did a push or disable
407     bool m_didEnd : 1;          // true if we popped or re-enabled
408     bool m_didCreateLayoutState : 1; // true if we actually made a layout state.
409 };
410
411 class LayoutStateDisabler {
412     WTF_MAKE_NONCOPYABLE(LayoutStateDisabler);
413 public:
414     LayoutStateDisabler(RenderView* view)
415         : m_view(view)
416     {
417         if (m_view)
418             m_view->disableLayoutState();
419     }
420
421     ~LayoutStateDisabler()
422     {
423         if (m_view)
424             m_view->enableLayoutState();
425     }
426 private:
427     RenderView* m_view;
428 };
429
430 } // namespace WebCore
431
432 #endif // RenderView_h