2d50bc61ea6d824acc7958a5c2679ef2e92e44f4
[WebKit-https.git] / WebCore / khtml / rendering / render_layer.h
1 /*
2  * Copyright (C) 2003 Apple Computer, Inc.
3  *
4  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5  *
6  * Other contributors:
7  *   Robert O'Callahan <roc+@cs.cmu.edu>
8  *   David Baron <dbaron@fas.harvard.edu>
9  *   Christian Biesinger <cbiesinger@web.de>
10  *   Randall Jesup <rjesup@wgate.com>
11  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
12  *   Josh Soref <timeless@mac.com>
13  *   Boris Zbarsky <bzbarsky@mit.edu>
14  *
15  * This library is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU Lesser General Public
17  * License as published by the Free Software Foundation; either
18  * version 2.1 of the License, or (at your option) any later version.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  *
29  * Alternatively, the contents of this file may be used under the terms
30  * of either the Mozilla Public License Version 1.1, found at
31  * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
32  * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
33  * (the "GPL"), in which case the provisions of the MPL or the GPL are
34  * applicable instead of those above.  If you wish to allow use of your
35  * version of this file only under the terms of one of those two
36  * licenses (the MPL or the GPL) and not to allow others to use your
37  * version of this file under the LGPL, indicate your decision by
38  * deletingthe provisions above and replace them with the notice and
39  * other provisions required by the MPL or the GPL, as the case may be.
40  * If you do not delete the provisions above, a recipient may use your
41  * version of this file under any of the LGPL, the MPL or the GPL.
42  */
43
44 #ifndef render_layer_h
45 #define render_layer_h
46
47 #include <qcolor.h>
48 #include <qrect.h>
49 #include <assert.h>
50
51 #include "render_object.h"
52
53 class QScrollBar;
54 template <class T> class QPtrVector;
55
56 namespace khtml {
57     class RenderStyle;
58     class RenderTable;
59     class CachedObject;
60     class RenderCanvas;
61     class RenderText;
62     class RenderFrameSet;
63     class RenderObject;
64     class RenderScrollMediator;
65     
66 class RenderScrollMediator: public QObject
67 {
68 public:
69     RenderScrollMediator(RenderLayer* layer)
70     :m_layer(layer) {}
71
72     void slotValueChanged(int);
73     
74 private:
75     RenderLayer* m_layer;
76 };
77
78 // This class handles the auto-scrolling of layers with overflow: marquee.
79 class Marquee: public QObject
80 {
81     Q_OBJECT
82     
83 public:
84     Marquee(RenderLayer* l);
85
86     void timerEvent(QTimerEvent*);
87
88     int speed() const { return m_speed; }
89     int marqueeSpeed() const;
90     EMarqueeDirection direction() const;
91     EMarqueeDirection reverseDirection() const { return static_cast<EMarqueeDirection>(-direction()); }
92     bool isHorizontal() const;
93     bool isUnfurlMarquee() const;
94     int unfurlPos() const { return m_unfurlPos; }
95
96     EWhiteSpace whiteSpace() { return m_whiteSpace; }
97     
98     int computePosition(EMarqueeDirection dir, bool stopAtClientEdge);
99
100     void setEnd(int end) { m_end = end; }
101     
102     void start();
103     void suspend();
104     
105     void updateMarqueeStyle();
106     void updateMarqueePosition();
107
108 private:
109     RenderLayer* m_layer;
110     int m_currentLoop;
111     int m_totalLoops;
112     int m_timerId;
113     int m_start;
114     int m_end;
115     int m_speed;
116     int m_unfurlPos;
117     bool m_reset;
118     bool m_suspended;
119     EWhiteSpace m_whiteSpace : 2;
120     EMarqueeDirection m_direction : 4;
121 };
122
123 class RenderLayer
124 {
125 public:
126 #ifdef APPLE_CHANGES
127     static QScrollBar* gScrollBar;
128 #endif
129     
130     RenderLayer(RenderObject* object);
131     ~RenderLayer();
132     
133     RenderObject* renderer() const { return m_object; }
134     RenderLayer *parent() const { return m_parent; }
135     RenderLayer *previousSibling() const { return m_previous; }
136     RenderLayer *nextSibling() const { return m_next; }
137
138     RenderLayer *firstChild() const { return m_first; }
139     RenderLayer *lastChild() const { return m_last; }
140
141     void addChild(RenderLayer *newChild, RenderLayer* beforeChild = 0);
142     RenderLayer* removeChild(RenderLayer *oldChild);
143
144     void removeOnlyThisLayer();
145     void insertOnlyThisLayer();
146
147     void repaintIncludingDescendants();
148     
149     void styleChanged();
150     
151     Marquee* marquee() const { return m_marquee; }
152     void suspendMarquees();
153
154 #if APPLE_CHANGES
155     bool isTransparent();
156     RenderLayer* transparentAncestor();
157     void beginTransparencyLayers(QPainter* p);
158 #endif
159     
160     RenderLayer* root() {
161         RenderLayer* curr = this;
162         while (curr->parent()) curr = curr->parent();
163         return curr;
164     }
165     
166     int xPos() const { return m_x; }
167     int yPos() const { return m_y; }
168     int width() const { return m_width; }
169     int height() const { return m_height; }
170
171     void setWidth(int w) { m_width = w; }
172     void setHeight(int h) { m_height = h; }
173
174     int scrollWidth();
175     int scrollHeight();
176     
177     void setPos( int xPos, int yPos ) {
178         m_x = xPos;
179         m_y = yPos;
180     }
181
182     // Scrolling methods for layers that can scroll their overflow.
183     void scrollOffset(int& x, int& y);
184     void subtractScrollOffset(int& x, int& y);
185     int scrollXOffset() { return m_scrollX; }
186     int scrollYOffset() { return m_scrollY; }
187     void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true);
188     void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY); }
189     void scrollToYOffset(int y) { scrollToOffset(m_scrollX, y); }
190     void setHasHorizontalScrollbar(bool hasScrollbar);
191     void setHasVerticalScrollbar(bool hasScrollbar);
192     QScrollBar* horizontalScrollbar() { return m_hBar; }
193     QScrollBar* verticalScrollbar() { return m_vBar; }
194     int verticalScrollbarWidth();
195     int horizontalScrollbarHeight();
196     void moveScrollbarsAside();
197     void positionScrollbars(const QRect& absBounds);
198 #ifdef APPLE_CHANGES
199     void paintScrollbars(QPainter* p, const QRect& damageRect);
200 #endif
201     void updateScrollInfoAfterLayout();
202     void slotValueChanged(int);
203     void updateScrollPositionFromScrollbars();
204
205     void updateLayerPosition();
206     void updateLayerPositions(bool doFullRepaint = false, bool checkForRepaint=true);
207     void computeRepaintRects();
208     void relativePositionOffset(int& relX, int& relY) {
209         relX += m_relX; relY += m_relY;
210     }
211
212     // Get the enclosing stacking context for this layer.  A stacking context is a layer
213     // that has a non-auto z-index.
214     RenderLayer* stackingContext() const;
215     bool isStackingContext() const { return !hasAutoZIndex() || renderer()->isCanvas(); }
216
217     void dirtyZOrderLists();
218     void updateZOrderLists();
219     QPtrVector<RenderLayer>* posZOrderList() const { return m_posZOrderList; }
220     QPtrVector<RenderLayer>* negZOrderList() const { return m_negZOrderList; }
221     
222     // Gets the nearest enclosing positioned ancestor layer (also includes
223     // the <html> layer and the root layer).
224     RenderLayer* enclosingPositionedAncestor() const;
225     
226     void convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const;
227     
228     bool hasAutoZIndex() const { return renderer()->style()->hasAutoZIndex(); }
229     int zIndex() const { return renderer()->style()->zIndex(); }
230
231     // The two main functions that use the layer system.  The paint method
232     // paints the layers that intersect the damage rect from back to
233     // front.  The nodeAtPoint method looks for mouse events by walking
234     // layers that intersect the point from front to back.
235     void paint(QPainter *p, const QRect& damageRect, bool selectionOnly=false, RenderObject *paintingRoot=0);
236     bool nodeAtPoint(RenderObject::NodeInfo& info, int x, int y);
237
238     // This method figures out our layerBounds in coordinates relative to
239     // |rootLayer}.  It also computes our background and foreground clip rects
240     // for painting/event handling.
241     void calculateRects(const RenderLayer* rootLayer, const QRect& paintDirtyRect, QRect& layerBounds,
242                         QRect& backgroundRect, QRect& foregroundRect);
243     void calculateClipRects(const RenderLayer* rootLayer, QRect& overflowClipRect,
244                             QRect& posClipRect, QRect& fixedClipRect);
245
246     bool intersectsDamageRect(const QRect& layerBounds, const QRect& damageRect) const;
247     bool containsPoint(int x, int y, const QRect& damageRect) const;
248     
249     void updateHoverActiveState(RenderObject::NodeInfo& info);
250     
251     QRect repaintRect() const { return m_repaintRect; }
252
253     void detach(RenderArena* renderArena);
254
255      // Overloaded new operator.  Derived classes must override operator new
256     // in order to allocate out of the RenderArena.
257     void* operator new(size_t sz, RenderArena* renderArena) throw();    
258
259     // Overridden to prevent the normal delete from being called.
260     void operator delete(void* ptr, size_t sz);
261         
262 private:
263     // The normal operator new is disallowed on all render objects.
264     void* operator new(size_t sz) throw();
265
266 private:
267     void setNextSibling(RenderLayer* next) { m_next = next; }
268     void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
269     void setParent(RenderLayer* parent) { m_parent = parent; }
270     void setFirstChild(RenderLayer* first) { m_first = first; }
271     void setLastChild(RenderLayer* last) { m_last = last; }
272
273     void collectLayers(QPtrVector<RenderLayer>*&, QPtrVector<RenderLayer>*&);
274
275     void paintLayer(RenderLayer* rootLayer, QPainter *p, const QRect& paintDirtyRect, 
276                     bool haveTransparency, bool selectionOnly, RenderObject *paintingRoot);
277     RenderLayer* nodeAtPointForLayer(RenderLayer* rootLayer, RenderObject::NodeInfo& info,
278                                      int x, int y, const QRect& hitTestRect);
279
280     void computeScrollDimensions(bool* needHBar = 0, bool* needVBar = 0);
281     
282 protected:   
283     RenderObject* m_object;
284     
285     RenderLayer* m_parent;
286     RenderLayer* m_previous;
287     RenderLayer* m_next;
288
289     RenderLayer* m_first;
290     RenderLayer* m_last;
291
292     QRect m_repaintRect; // Cached repaint rects. Used by layout.
293     QRect m_fullRepaintRect;
294
295     // Our current relative position offset.
296     int m_relX;
297     int m_relY;
298
299     // Our (x,y) coordinates are in our parent layer's coordinate space.
300     int m_x;
301     int m_y;
302
303     // The layer's width/height
304     int m_width;
305     int m_height;
306     
307     // Our scroll offsets if the view is scrolled.
308     int m_scrollX;
309     int m_scrollY;
310     
311     // The width/height of our scrolled area.
312     int m_scrollWidth;
313     int m_scrollHeight;
314     
315     // For layers with overflow, we have a pair of scrollbars.
316     QScrollBar* m_hBar;
317     QScrollBar* m_vBar;
318     RenderScrollMediator* m_scrollMediator;
319
320     // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the
321     // descendant layers within the stacking context that have z-indices of 0 or greater
322     // (auto will count as 0).  m_negZOrderList holds descendants within our stacking context with negative
323     // z-indices.
324     QPtrVector<RenderLayer>* m_posZOrderList;
325     QPtrVector<RenderLayer>* m_negZOrderList;
326     
327     bool m_scrollDimensionsDirty : 1;
328     bool m_zOrderListsDirty : 1;
329 #if APPLE_CHANGES
330     bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
331                                  // we ended up painting this layer or any descendants (and therefore need to
332                                  // blend).
333 #endif
334
335     Marquee* m_marquee; // Used by layers with overflow:marquee
336 };
337
338 }; // namespace
339 #endif