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