File indexing completed on 2024-04-28 15:24:05
0001 /* 0002 * Copyright (C) 2003 Apple Computer, Inc. 0003 * 0004 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 0005 * 0006 * Other contributors: 0007 * Robert O'Callahan <roc+@cs.cmu.edu> 0008 * David Baron <dbaron@fas.harvard.edu> 0009 * Christian Biesinger <cbiesinger@web.de> 0010 * Randall Jesup <rjesup@wgate.com> 0011 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> 0012 * Josh Soref <timeless@mac.com> 0013 * Boris Zbarsky <bzbarsky@mit.edu> 0014 * 0015 * This library is free software; you can redistribute it and/or 0016 * modify it under the terms of the GNU Lesser General Public 0017 * License as published by the Free Software Foundation; either 0018 * version 2.1 of the License, or (at your option) any later version. 0019 * 0020 * This library is distributed in the hope that it will be useful, 0021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0023 * Lesser General Public License for more details. 0024 * 0025 * You should have received a copy of the GNU Lesser General Public 0026 * License along with this library; if not, write to the Free Software 0027 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0028 * 0029 * Alternatively, the contents of this file may be used under the terms 0030 * of either the Mozilla Public License Version 1.1, found at 0031 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public 0032 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html 0033 * (the "GPL"), in which case the provisions of the MPL or the GPL are 0034 * applicable instead of those above. If you wish to allow use of your 0035 * version of this file only under the terms of one of those two 0036 * licenses (the MPL or the GPL) and not to allow others to use your 0037 * version of this file under the LGPL, indicate your decision by 0038 * deletingthe provisions above and replace them with the notice and 0039 * other provisions required by the MPL or the GPL, as the case may be. 0040 * If you do not delete the provisions above, a recipient may use your 0041 * version of this file under any of the LGPL, the MPL or the GPL. 0042 */ 0043 0044 #ifndef render_layer_h 0045 #define render_layer_h 0046 0047 #include <QColor> 0048 #include <QRect> 0049 #include <assert.h> 0050 0051 #include "render_object.h" 0052 0053 //template <class T*> class QVector; 0054 0055 namespace khtml 0056 { 0057 class RenderObject; 0058 class RenderScrollMediator; 0059 class ScrollBarWidget; 0060 0061 class RenderScrollMediator: public QObject 0062 { 0063 Q_OBJECT 0064 public: 0065 RenderScrollMediator(RenderLayer *layer) 0066 : m_layer(layer), m_waitingForUpdate(false) {} 0067 0068 public Q_SLOTS: 0069 void slotValueChanged(); 0070 0071 private: 0072 RenderLayer *m_layer; 0073 bool m_waitingForUpdate; 0074 }; 0075 0076 // This class handles the auto-scrolling of layers with overflow: marquee. 0077 class Marquee: public QObject 0078 { 0079 Q_OBJECT 0080 0081 public: 0082 Marquee(RenderLayer *l); 0083 0084 void timerEvent(QTimerEvent *) override; 0085 0086 int speed() const 0087 { 0088 return m_speed; 0089 } 0090 int marqueeSpeed() const; 0091 EMarqueeDirection direction() const; 0092 EMarqueeDirection reverseDirection() const 0093 { 0094 return static_cast<EMarqueeDirection>(-direction()); 0095 } 0096 bool isHorizontal() const; 0097 bool isUnfurlMarquee() const; 0098 int unfurlPos() const 0099 { 0100 return m_unfurlPos; 0101 } 0102 0103 EWhiteSpace whiteSpace() 0104 { 0105 return KDE_CAST_BF_ENUM(EWhiteSpace, m_whiteSpace); 0106 } 0107 0108 int computePosition(EMarqueeDirection dir, bool stopAtClientEdge); 0109 0110 void setEnd(int end) 0111 { 0112 m_end = end; 0113 } 0114 0115 void start(); 0116 void suspend(); 0117 void stop(); 0118 0119 void updateMarqueeStyle(); 0120 void updateMarqueePosition(); 0121 0122 private: 0123 RenderLayer *m_layer; 0124 int m_currentLoop; 0125 int m_totalLoops; 0126 int m_timerId; 0127 int m_start; 0128 int m_end; 0129 int m_speed; 0130 int m_unfurlPos; 0131 bool m_reset: 1; 0132 bool m_suspended: 1; 0133 bool m_stopped: 1; 0134 KDE_BF_ENUM(EWhiteSpace) m_whiteSpace : 3; 0135 KDE_BF_ENUM(EMarqueeDirection) m_direction : 4; 0136 }; 0137 0138 class RenderLayer 0139 { 0140 public: 0141 static ScrollBarWidget *gScrollBar; 0142 0143 RenderLayer(RenderObject *object); 0144 ~RenderLayer(); 0145 0146 RenderObject *renderer() const 0147 { 0148 return m_object; 0149 } 0150 RenderLayer *parent() const 0151 { 0152 return m_parent; 0153 } 0154 RenderLayer *previousSibling() const 0155 { 0156 return m_previous; 0157 } 0158 RenderLayer *nextSibling() const 0159 { 0160 return m_next; 0161 } 0162 0163 RenderLayer *firstChild() const 0164 { 0165 return m_first; 0166 } 0167 RenderLayer *lastChild() const 0168 { 0169 return m_last; 0170 } 0171 0172 void addChild(RenderLayer *newChild, RenderLayer *beforeChild = nullptr); 0173 RenderLayer *removeChild(RenderLayer *oldChild); 0174 0175 void removeOnlyThisLayer(); 0176 void insertOnlyThisLayer(); 0177 0178 void styleChanged(); 0179 0180 Marquee *marquee() const 0181 { 0182 return m_marquee; 0183 } 0184 void suspendMarquees(); 0185 0186 bool isOverflowOnly() const 0187 { 0188 return m_isOverflowOnly; 0189 } 0190 0191 bool isTransparent() const; 0192 RenderLayer *transparentAncestor() const; 0193 0194 RenderLayer *root() 0195 { 0196 RenderLayer *curr = this; 0197 while (curr->parent()) { 0198 curr = curr->parent(); 0199 } 0200 return curr; 0201 } 0202 0203 int xPos() const 0204 { 0205 return m_x; 0206 } 0207 int yPos() const 0208 { 0209 return m_y; 0210 } 0211 0212 int width() const; 0213 int height() const; 0214 0215 int scrollWidth() const 0216 { 0217 return m_scrollWidth; 0218 } 0219 int scrollHeight() const 0220 { 0221 return m_scrollHeight; 0222 } 0223 0224 void resize(int w, int h) 0225 { 0226 m_scrollWidth = w; m_scrollHeight = h; 0227 } 0228 0229 void setPos(int xPos, int yPos) 0230 { 0231 m_x = xPos; 0232 m_y = yPos; 0233 } 0234 0235 // Scrolling methods for layers that can scroll their overflow. 0236 void scrollOffset(int &x, int &y); 0237 void subtractScrollOffset(int &x, int &y); 0238 void checkInlineRelOffset(const RenderObject *o, int &x, int &y); 0239 int scrollXOffset() 0240 { 0241 return m_scrollX + m_scrollXOrigin; 0242 } 0243 int scrollYOffset() 0244 { 0245 return m_scrollY; 0246 } 0247 void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true, bool dispatchEvent = true); 0248 void scrollToXOffset(int x) 0249 { 0250 scrollToOffset(x, m_scrollY); 0251 } 0252 void scrollToYOffset(int y) 0253 { 0254 scrollToOffset(m_scrollX + m_scrollXOrigin, y); 0255 } 0256 void resetXOffset() 0257 { 0258 scrollToOffset(0, m_scrollY, false, false, false); 0259 } 0260 void resetYOffset() 0261 { 0262 scrollToOffset(m_scrollX + m_scrollXOrigin, 0, false, false, false); 0263 } 0264 void showScrollbar(Qt::Orientation, bool); 0265 ScrollBarWidget *horizontalScrollbar() 0266 { 0267 return m_hBar; 0268 } 0269 ScrollBarWidget *verticalScrollbar() 0270 { 0271 return m_vBar; 0272 } 0273 bool hasReversedScrollbar() const; 0274 int verticalScrollbarWidth(); 0275 int horizontalScrollbarHeight(); 0276 void positionScrollbars(const QRect &damageRect); 0277 void paintScrollbars(RenderObject::PaintInfo &pI); 0278 void checkScrollbarsAfterLayout(); 0279 void slotValueChanged(int); 0280 void repaint(Priority p = NormalPriority, bool markForRepaint = false); 0281 void updateScrollPositionFromScrollbars(); 0282 0283 void updateLayerPosition(); 0284 void updateLayerPositions(RenderLayer *rootLayer, bool doFullRepaint = false, bool checkForRepaint = false); 0285 0286 // Get the enclosing stacking context for this layer. A stacking context is a layer 0287 // that has a non-auto z-index. 0288 RenderLayer *stackingContext() const; 0289 bool isStackingContext() const 0290 { 0291 return !hasAutoZIndex() || renderer()->isCanvas(); 0292 } 0293 0294 void dirtyZOrderLists(); 0295 void updateZOrderLists(); 0296 QVector<RenderLayer *> *posZOrderList() const 0297 { 0298 return m_posZOrderList; 0299 } 0300 QVector<RenderLayer *> *negZOrderList() const 0301 { 0302 return m_negZOrderList; 0303 } 0304 0305 void dirtyOverflowList(); 0306 void updateOverflowList(); 0307 QVector<RenderLayer *> *overflowList() const 0308 { 0309 return m_overflowList; 0310 } 0311 0312 bool hasVisibleContent() const 0313 { 0314 return m_hasVisibleContent; 0315 } 0316 void setHasVisibleContent(bool b); 0317 void dirtyVisibleContentStatus(); 0318 0319 void setHasOverlaidWidgets(bool b = true) 0320 { 0321 m_hasOverlaidWidgets = b; 0322 } 0323 bool hasOverlaidWidgets() const 0324 { 0325 return m_hasOverlaidWidgets; 0326 } 0327 QRegion getMask() const 0328 { 0329 return m_region; 0330 } 0331 QRegion paintedRegion(RenderLayer *rootLayer); 0332 void updateWidgetMasks(RenderLayer *rootLayer); 0333 0334 // Gets the nearest enclosing positioned ancestor layer (also includes 0335 // the <html> layer and the root layer). 0336 RenderLayer *enclosingPositionedAncestor() const; 0337 0338 void convertToLayerCoords(const RenderLayer *ancestorLayer, int &x, int &y) const; 0339 0340 bool hasAutoZIndex() const 0341 { 0342 return renderer()->style()->hasAutoZIndex(); 0343 } 0344 int zIndex() const 0345 { 0346 return renderer()->style()->zIndex(); 0347 } 0348 0349 // The two main functions that use the layer system. The paint method 0350 // paints the layers that intersect the damage rect from back to 0351 // front. The nodeAtPoint method looks for mouse events by walking 0352 // layers that intersect the point from front to back. 0353 KHTML_EXPORT void paint(QPainter *p, const QRect &damageRect, bool selectionOnly = false); 0354 bool nodeAtPoint(RenderObject::NodeInfo &info, int x, int y); 0355 0356 // This method figures out our layerBounds in coordinates relative to 0357 // |rootLayer}. It also computes our background and foreground clip rects 0358 // for painting/event handling. 0359 void calculateRects(const RenderLayer *rootLayer, const QRect &paintDirtyRect, QRect &layerBounds, 0360 QRect &backgroundRect, QRect &foregroundRect); 0361 void calculateClipRects(const RenderLayer *rootLayer, QRect &overflowClipRect, 0362 QRect &posClipRect, QRect &fixedClipRect); 0363 0364 bool intersectsDamageRect(const QRect &layerBounds, const QRect &damageRect) const; 0365 bool containsPoint(int x, int y, const QRect &damageRect) const; 0366 0367 void updateHoverActiveState(RenderObject::NodeInfo &info); 0368 0369 void detach(RenderArena *renderArena); 0370 0371 #ifdef ENABLE_DUMP 0372 KHTML_EXPORT void dump(QTextStream &stream, const QString &ind = QString()); 0373 #endif 0374 0375 // Overloaded new operator. Derived classes must override operator new 0376 // in order to allocate out of the RenderArena. 0377 void *operator new(size_t sz, RenderArena *renderArena) throw(); 0378 0379 // Overridden to prevent the normal delete from being called. 0380 void operator delete(void *ptr, size_t sz); 0381 0382 private: 0383 // The normal operator new is disallowed on all render objects. 0384 void *operator new(size_t sz) throw(); 0385 0386 private: 0387 void setNextSibling(RenderLayer *next) 0388 { 0389 m_next = next; 0390 } 0391 void setPreviousSibling(RenderLayer *prev) 0392 { 0393 m_previous = prev; 0394 } 0395 void setParent(RenderLayer *parent) 0396 { 0397 m_parent = parent; 0398 } 0399 void setFirstChild(RenderLayer *first) 0400 { 0401 m_first = first; 0402 } 0403 void setLastChild(RenderLayer *last) 0404 { 0405 m_last = last; 0406 } 0407 0408 void collectLayers(QVector<RenderLayer *> *&, QVector<RenderLayer *> *&); 0409 0410 KHTML_EXPORT void paintLayer(RenderLayer *rootLayer, QPainter *p, const QRect &paintDirtyRect, bool selectionOnly = false); 0411 RenderLayer *nodeAtPointForLayer(RenderLayer *rootLayer, RenderObject::NodeInfo &info, 0412 int x, int y, const QRect &hitTestRect); 0413 bool shouldBeOverflowOnly() const; 0414 0415 void childVisibilityChanged(bool newVisibility); 0416 void dirtyVisibleDescendantStatus(); 0417 void updateVisibilityStatus(); 0418 0419 protected: 0420 void setClip(QPainter *p, const QRect &paintDirtyRect, const QRect &clipRect, bool setup = false); 0421 void restoreClip(QPainter *p, const QRect &paintDirtyRect, const QRect &clipRect, bool cleanup = false); 0422 0423 RenderObject *m_object; 0424 0425 RenderLayer *m_parent; 0426 RenderLayer *m_previous; 0427 RenderLayer *m_next; 0428 0429 RenderLayer *m_first; 0430 RenderLayer *m_last; 0431 0432 // Our (x,y) coordinates are in our parent layer's coordinate space. 0433 int m_x; 0434 int m_y; 0435 0436 // Our scroll offsets if the view is scrolled. 0437 int m_scrollX; 0438 int m_scrollY; 0439 0440 // the reference for our x offset (will vary depending on layout direction) 0441 int m_scrollXOrigin; 0442 0443 // The width/height of our scrolled area. 0444 int m_scrollWidth; 0445 int m_scrollHeight; 0446 0447 // For layers with overflow, we have a pair of scrollbars. 0448 ScrollBarWidget *m_hBar; 0449 ScrollBarWidget *m_vBar; 0450 QPixmap *m_buffer[2]; 0451 0452 RenderScrollMediator *m_scrollMediator; 0453 0454 // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the 0455 // descendant layers within the stacking context that have z-indices of 0 or greater 0456 // (auto will count as 0). m_negZOrderList holds descendants within our stacking context with negative 0457 // z-indices. 0458 QVector<RenderLayer *> *m_posZOrderList; 0459 QVector<RenderLayer *> *m_negZOrderList; 0460 0461 // This list contains our overflow child layers. 0462 QVector<RenderLayer *> *m_overflowList; 0463 0464 bool m_zOrderListsDirty: 1; 0465 bool m_overflowListDirty: 1; 0466 bool m_isOverflowOnly: 1; 0467 bool m_markedForRepaint: 1; 0468 bool m_hasOverlaidWidgets: 1; 0469 bool m_visibleContentStatusDirty : 1; 0470 bool m_hasVisibleContent : 1; 0471 bool m_visibleDescendantStatusDirty : 1; 0472 bool m_hasVisibleDescendant : 1; 0473 bool m_inScrollbarRelayout : 1; 0474 bool m_wasStackingContext : 1; // set to 1 when last style application 0475 // establised us as a stacking context 0476 0477 QRect m_visibleRect; 0478 0479 QRegion m_region; // used by overlaid (non z-order aware) widgets 0480 0481 Marquee *m_marquee; // Used by layers with overflow:marquee 0482 }; 0483 0484 } // namespace 0485 #endif