1a185827aec89e87a25bf74bf3e8a3c2c42ce028
[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 class ClipRects
79 {
80 public:
81     ClipRects(const QRect& r) :m_overflowClipRect(r), m_fixedClipRect(r), m_posClipRect(r), m_refCnt(0) {}
82     ClipRects(const QRect& o, const QRect& f, const QRect& p)
83       :m_overflowClipRect(o), m_fixedClipRect(f), m_posClipRect(p), m_refCnt(0) {}
84
85     const QRect& overflowClipRect() { return m_overflowClipRect; }
86     const QRect& fixedClipRect() { return m_fixedClipRect; }
87     const QRect& posClipRect() { return m_posClipRect; }
88
89     void ref() { m_refCnt++; }
90     void deref(RenderArena* renderArena) { if (--m_refCnt == 0) detach(renderArena); }
91     
92     void detach(RenderArena* renderArena);
93
94     // Overloaded new operator.
95     void* operator new(size_t sz, RenderArena* renderArena) throw();    
96
97     // Overridden to prevent the normal delete from being called.
98     void operator delete(void* ptr, size_t sz);
99         
100 private:
101     // The normal operator new is disallowed on all render objects.
102     void* operator new(size_t sz) throw();
103
104 private:
105     QRect m_overflowClipRect;
106     QRect m_fixedClipRect;
107     QRect m_posClipRect;
108     uint m_refCnt;
109 };
110
111 // This class handles the auto-scrolling of layers with overflow: marquee.
112 class Marquee: public QObject
113 {
114     Q_OBJECT
115     
116 public:
117     Marquee(RenderLayer* l);
118
119     void timerEvent(QTimerEvent*);
120
121     int speed() const { return m_speed; }
122     int marqueeSpeed() const;
123     EMarqueeDirection direction() const;
124     EMarqueeDirection reverseDirection() const { return static_cast<EMarqueeDirection>(-direction()); }
125     bool isHorizontal() const;
126     bool isUnfurlMarquee() const;
127     int unfurlPos() const { return m_unfurlPos; }
128
129     EWhiteSpace whiteSpace() { return m_whiteSpace; }
130     
131     int computePosition(EMarqueeDirection dir, bool stopAtClientEdge);
132
133     void setEnd(int end) { m_end = end; }
134     
135     void start();
136     void suspend();
137     void stop();
138
139     void updateMarqueeStyle();
140     void updateMarqueePosition();
141
142 private:
143     RenderLayer* m_layer;
144     int m_currentLoop;
145     int m_totalLoops;
146     int m_timerId;
147     int m_start;
148     int m_end;
149     int m_speed;
150     int m_unfurlPos;
151     bool m_reset: 1;
152     bool m_suspended : 1;
153     bool m_stopped : 1;
154     EWhiteSpace m_whiteSpace : 2;
155     EMarqueeDirection m_direction : 4;
156 };
157
158 class RenderLayer
159 {
160 public:
161 #ifdef APPLE_CHANGES
162     static QScrollBar* gScrollBar;
163 #endif
164     
165     RenderLayer(RenderObject* object);
166     ~RenderLayer();
167     
168     RenderObject* renderer() const { return m_object; }
169     RenderLayer *parent() const { return m_parent; }
170     RenderLayer *previousSibling() const { return m_previous; }
171     RenderLayer *nextSibling() const { return m_next; }
172
173     RenderLayer *firstChild() const { return m_first; }
174     RenderLayer *lastChild() const { return m_last; }
175
176     void addChild(RenderLayer *newChild, RenderLayer* beforeChild = 0);
177     RenderLayer* removeChild(RenderLayer *oldChild);
178
179     void removeOnlyThisLayer();
180     void insertOnlyThisLayer();
181
182     void repaintIncludingDescendants();
183     
184     void styleChanged();
185     
186     Marquee* marquee() const { return m_marquee; }
187     void suspendMarquees();
188
189 #if APPLE_CHANGES
190     bool isTransparent();
191     RenderLayer* transparentAncestor();
192     void beginTransparencyLayers(QPainter* p);
193 #endif
194     
195     RenderLayer* root() {
196         RenderLayer* curr = this;
197         while (curr->parent()) curr = curr->parent();
198         return curr;
199     }
200     
201     int xPos() const { return m_x; }
202     int yPos() const { return m_y; }
203     int width() const { return m_width; }
204     int height() const { return m_height; }
205
206     void setWidth(int w) { m_width = w; }
207     void setHeight(int h) { m_height = h; }
208
209     int scrollWidth();
210     int scrollHeight();
211     
212     void setPos( int xPos, int yPos ) {
213         m_x = xPos;
214         m_y = yPos;
215     }
216
217     // Scrolling methods for layers that can scroll their overflow.
218     void scrollOffset(int& x, int& y);
219     void subtractScrollOffset(int& x, int& y);
220     int scrollXOffset() const { return m_scrollX; }
221     int scrollYOffset() const { return m_scrollY; }
222     void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true);
223     void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY); }
224     void scrollToYOffset(int y) { scrollToOffset(m_scrollX, y); }
225     void setHasHorizontalScrollbar(bool hasScrollbar);
226     void setHasVerticalScrollbar(bool hasScrollbar);
227     QScrollBar* horizontalScrollbar() { return m_hBar; }
228     QScrollBar* verticalScrollbar() { return m_vBar; }
229     int verticalScrollbarWidth();
230     int horizontalScrollbarHeight();
231     void moveScrollbarsAside();
232     void positionScrollbars(const QRect& absBounds);
233 #ifdef APPLE_CHANGES
234     void paintScrollbars(QPainter* p, const QRect& damageRect);
235 #endif
236     void updateScrollInfoAfterLayout();
237     void slotValueChanged(int);
238     void updateScrollPositionFromScrollbars();
239     bool scroll(KWQScrollDirection direction, KWQScrollGranularity granularity, float multiplier=1.0);
240     
241     void updateLayerPosition();
242     void updateLayerPositions(bool doFullRepaint = false, bool checkForRepaint=true);
243     void computeRepaintRects();
244     void relativePositionOffset(int& relX, int& relY) {
245         relX += m_relX; relY += m_relY;
246     }
247      
248     void clearClipRects();
249     void clearClipRect();
250
251     // Get the enclosing stacking context for this layer.  A stacking context is a layer
252     // that has a non-auto z-index.
253     RenderLayer* stackingContext() const;
254     bool isStackingContext() const { return !hasAutoZIndex() || renderer()->isCanvas(); }
255
256     void dirtyZOrderLists();
257     void updateZOrderLists();
258     QPtrVector<RenderLayer>* posZOrderList() const { return m_posZOrderList; }
259     QPtrVector<RenderLayer>* negZOrderList() const { return m_negZOrderList; }
260     
261     // Gets the nearest enclosing positioned ancestor layer (also includes
262     // the <html> layer and the root layer).
263     RenderLayer* enclosingPositionedAncestor() const;
264     
265     void convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const;
266     
267     bool hasAutoZIndex() const { return renderer()->style()->hasAutoZIndex(); }
268     int zIndex() const { return renderer()->style()->zIndex(); }
269
270     // The two main functions that use the layer system.  The paint method
271     // paints the layers that intersect the damage rect from back to
272     // front.  The hitTest method looks for mouse events by walking
273     // layers that intersect the point from front to back.
274     void paint(QPainter *p, const QRect& damageRect, bool selectionOnly=false, RenderObject *paintingRoot=0);
275     bool hitTest(RenderObject::NodeInfo& info, int x, int y);
276
277     // This method figures out our layerBounds in coordinates relative to
278     // |rootLayer}.  It also computes our background and foreground clip rects
279     // for painting/event handling.
280     void calculateRects(const RenderLayer* rootLayer, const QRect& paintDirtyRect, QRect& layerBounds,
281                         QRect& backgroundRect, QRect& foregroundRect);
282     void calculateClipRects(const RenderLayer* rootLayer);
283     ClipRects* clipRects() const { return m_clipRects; }
284
285     bool intersectsDamageRect(const QRect& layerBounds, const QRect& damageRect) const;
286     bool containsPoint(int x, int y, const QRect& damageRect) const;
287     
288     void updateHoverActiveState(RenderObject::NodeInfo& info);
289     
290     QRect repaintRect() const { return m_repaintRect; }
291
292     void detach(RenderArena* renderArena);
293
294      // Overloaded new operator.  Derived classes must override operator new
295     // in order to allocate out of the RenderArena.
296     void* operator new(size_t sz, RenderArena* renderArena) throw();    
297
298     // Overridden to prevent the normal delete from being called.
299     void operator delete(void* ptr, size_t sz);
300         
301 private:
302     // The normal operator new is disallowed on all render objects.
303     void* operator new(size_t sz) throw();
304
305 private:
306     void setNextSibling(RenderLayer* next) { m_next = next; }
307     void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
308     void setParent(RenderLayer* parent) { m_parent = parent; }
309     void setFirstChild(RenderLayer* first) { m_first = first; }
310     void setLastChild(RenderLayer* last) { m_last = last; }
311
312     void collectLayers(QPtrVector<RenderLayer>*&, QPtrVector<RenderLayer>*&);
313
314     void paintLayer(RenderLayer* rootLayer, QPainter *p, const QRect& paintDirtyRect, 
315                     bool haveTransparency, bool selectionOnly, RenderObject *paintingRoot);
316     RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderObject::NodeInfo& info,
317                               int x, int y, const QRect& hitTestRect);
318     void computeScrollDimensions(bool* needHBar = 0, bool* needVBar = 0);
319
320 protected:   
321     RenderObject* m_object;
322     
323     RenderLayer* m_parent;
324     RenderLayer* m_previous;
325     RenderLayer* m_next;
326
327     RenderLayer* m_first;
328     RenderLayer* m_last;
329
330     QRect m_repaintRect; // Cached repaint rects. Used by layout.
331     QRect m_fullRepaintRect;
332
333     // Our current relative position offset.
334     int m_relX;
335     int m_relY;
336
337     // Our (x,y) coordinates are in our parent layer's coordinate space.
338     int m_x;
339     int m_y;
340
341     // The layer's width/height
342     int m_width;
343     int m_height;
344     
345     // Our scroll offsets if the view is scrolled.
346     int m_scrollX;
347     int m_scrollY;
348     
349     // The width/height of our scrolled area.
350     int m_scrollWidth;
351     int m_scrollHeight;
352     
353     // For layers with overflow, we have a pair of scrollbars.
354     QScrollBar* m_hBar;
355     QScrollBar* m_vBar;
356     RenderScrollMediator* m_scrollMediator;
357
358     // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the
359     // descendant layers within the stacking context that have z-indices of 0 or greater
360     // (auto will count as 0).  m_negZOrderList holds descendants within our stacking context with negative
361     // z-indices.
362     QPtrVector<RenderLayer>* m_posZOrderList;
363     QPtrVector<RenderLayer>* m_negZOrderList;
364     
365     ClipRects* m_clipRects;      // Cached clip rects used when painting and hit testing.
366
367     bool m_scrollDimensionsDirty : 1;
368     bool m_zOrderListsDirty : 1;
369
370 #if APPLE_CHANGES
371     bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
372                                  // we ended up painting this layer or any descendants (and therefore need to
373                                  // blend).
374 #endif
375
376     Marquee* m_marquee; // Used by layers with overflow:marquee
377 };
378
379 }; // namespace
380 #endif