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