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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 RenderLayer_h 45 #define RenderLayer_h 46 47 #include "ScrollbarClient.h" 48 #include "RenderBox.h" 49 #include "Timer.h" 50 #include <wtf/OwnPtr.h> 51 52 namespace WebCore { 53 54 class TransformationMatrix; 55 class CachedResource; 56 class HitTestResult; 57 class RenderFrameSet; 58 class RenderMarquee; 59 class RenderReplica; 60 class RenderScrollbarPart; 61 class RenderStyle; 62 class RenderTable; 63 class RenderText; 64 class RenderView; 65 class Scrollbar; 66 67 struct HitTestRequest; 68 69 class ClipRects { 70 public: ClipRects()71 ClipRects() 72 : m_refCnt(0) 73 , m_fixed(false) 74 { 75 } 76 ClipRects(const IntRect & r)77 ClipRects(const IntRect& r) 78 : m_overflowClipRect(r) 79 , m_fixedClipRect(r) 80 , m_posClipRect(r) 81 , m_refCnt(0) 82 , m_fixed(false) 83 { 84 } 85 ClipRects(const ClipRects & other)86 ClipRects(const ClipRects& other) 87 : m_overflowClipRect(other.overflowClipRect()) 88 , m_fixedClipRect(other.fixedClipRect()) 89 , m_posClipRect(other.posClipRect()) 90 , m_refCnt(0) 91 , m_fixed(other.fixed()) 92 { 93 } 94 reset(const IntRect & r)95 void reset(const IntRect& r) 96 { 97 m_overflowClipRect = r; 98 m_fixedClipRect = r; 99 m_posClipRect = r; 100 m_fixed = false; 101 } 102 overflowClipRect()103 const IntRect& overflowClipRect() const { return m_overflowClipRect; } setOverflowClipRect(const IntRect & r)104 void setOverflowClipRect(const IntRect& r) { m_overflowClipRect = r; } 105 fixedClipRect()106 const IntRect& fixedClipRect() const { return m_fixedClipRect; } setFixedClipRect(const IntRect & r)107 void setFixedClipRect(const IntRect&r) { m_fixedClipRect = r; } 108 posClipRect()109 const IntRect& posClipRect() const { return m_posClipRect; } setPosClipRect(const IntRect & r)110 void setPosClipRect(const IntRect& r) { m_posClipRect = r; } 111 fixed()112 bool fixed() const { return m_fixed; } setFixed(bool fixed)113 void setFixed(bool fixed) { m_fixed = fixed; } 114 ref()115 void ref() { m_refCnt++; } deref(RenderArena * renderArena)116 void deref(RenderArena* renderArena) { if (--m_refCnt == 0) destroy(renderArena); } 117 118 void destroy(RenderArena*); 119 120 // Overloaded new operator. 121 void* operator new(size_t, RenderArena*) throw(); 122 123 // Overridden to prevent the normal delete from being called. 124 void operator delete(void*, size_t); 125 126 bool operator==(const ClipRects& other) const 127 { 128 return m_overflowClipRect == other.overflowClipRect() && 129 m_fixedClipRect == other.fixedClipRect() && 130 m_posClipRect == other.posClipRect() && 131 m_fixed == other.fixed(); 132 } 133 134 ClipRects& operator=(const ClipRects& other) 135 { 136 m_overflowClipRect = other.overflowClipRect(); 137 m_fixedClipRect = other.fixedClipRect(); 138 m_posClipRect = other.posClipRect(); 139 m_fixed = other.fixed(); 140 return *this; 141 } 142 143 private: 144 // The normal operator new is disallowed on all render objects. 145 void* operator new(size_t) throw(); 146 147 private: 148 IntRect m_overflowClipRect; 149 IntRect m_fixedClipRect; 150 IntRect m_posClipRect; 151 unsigned m_refCnt : 31; 152 bool m_fixed : 1; 153 }; 154 155 class RenderLayer : public ScrollbarClient { 156 public: 157 enum ScrollBehavior { 158 noScroll, 159 alignCenter, 160 alignTop, 161 alignBottom, 162 alignLeft, 163 alignRight, 164 alignToClosestEdge 165 }; 166 167 struct ScrollAlignment { 168 ScrollBehavior m_rectVisible; 169 ScrollBehavior m_rectHidden; 170 ScrollBehavior m_rectPartial; 171 }; 172 173 friend class RenderReplica; 174 175 static const ScrollAlignment gAlignCenterIfNeeded; 176 static const ScrollAlignment gAlignToEdgeIfNeeded; 177 static const ScrollAlignment gAlignCenterAlways; 178 static const ScrollAlignment gAlignTopAlways; 179 static const ScrollAlignment gAlignBottomAlways; 180 getVisibleBehavior(const ScrollAlignment & s)181 static ScrollBehavior getVisibleBehavior(const ScrollAlignment& s) { return s.m_rectVisible; } getPartialBehavior(const ScrollAlignment & s)182 static ScrollBehavior getPartialBehavior(const ScrollAlignment& s) { return s.m_rectPartial; } getHiddenBehavior(const ScrollAlignment & s)183 static ScrollBehavior getHiddenBehavior(const ScrollAlignment& s) { return s.m_rectHidden; } 184 185 RenderLayer(RenderBox*); 186 ~RenderLayer(); 187 renderer()188 RenderBox* renderer() const { return m_renderer; } parent()189 RenderLayer* parent() const { return m_parent; } previousSibling()190 RenderLayer* previousSibling() const { return m_previous; } nextSibling()191 RenderLayer* nextSibling() const { return m_next; } firstChild()192 RenderLayer* firstChild() const { return m_first; } lastChild()193 RenderLayer* lastChild() const { return m_last; } 194 195 void addChild(RenderLayer* newChild, RenderLayer* beforeChild = 0); 196 RenderLayer* removeChild(RenderLayer*); 197 198 void removeOnlyThisLayer(); 199 void insertOnlyThisLayer(); 200 201 void repaintIncludingDescendants(); 202 203 void styleChanged(RenderStyle::Diff, const RenderStyle*); 204 marquee()205 RenderMarquee* marquee() const { return m_marquee; } 206 void suspendMarquees(); 207 isOverflowOnly()208 bool isOverflowOnly() const { return m_isOverflowOnly; } 209 210 bool requiresSlowRepaints() const; 211 212 bool isTransparent() const; 213 RenderLayer* transparentAncestor(); 214 void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer); 215 hasReflection()216 bool hasReflection() const { return renderer()->hasReflection(); } reflection()217 RenderReplica* reflection() const { return m_reflection; } 218 RenderLayer* reflectionLayer() const; 219 root()220 const RenderLayer* root() const 221 { 222 const RenderLayer* curr = this; 223 while (curr->parent()) 224 curr = curr->parent(); 225 return curr; 226 } 227 xPos()228 int xPos() const { return m_x; } yPos()229 int yPos() const { return m_y; } setPos(int xPos,int yPos)230 void setPos(int xPos, int yPos) 231 { 232 m_x = xPos; 233 m_y = yPos; 234 } 235 width()236 int width() const { return m_width; } height()237 int height() const { return m_height; } setWidth(int w)238 void setWidth(int w) { m_width = w; } setHeight(int h)239 void setHeight(int h) { m_height = h; } 240 241 int scrollWidth(); 242 int scrollHeight(); 243 244 void panScrollFromPoint(const IntPoint&); 245 246 // Scrolling methods for layers that can scroll their overflow. 247 void scrollByRecursively(int xDelta, int yDelta); 248 void addScrolledContentOffset(int& x, int& y) const; 249 void subtractScrolledContentOffset(int& x, int& y) const; scrolledContentOffset()250 IntSize scrolledContentOffset() const { return IntSize(scrollXOffset() + m_scrollLeftOverflow, scrollYOffset()); } 251 scrollXOffset()252 int scrollXOffset() const { return m_scrollX + m_scrollOriginX; } scrollYOffset()253 int scrollYOffset() const { return m_scrollY; } 254 255 void scrollToOffset(int x, int y, bool updateScrollbars = true, bool repaint = true); scrollToXOffset(int x)256 void scrollToXOffset(int x) { scrollToOffset(x, m_scrollY); } scrollToYOffset(int y)257 void scrollToYOffset(int y) { scrollToOffset(m_scrollX + m_scrollOriginX, y); } 258 void scrollRectToVisible(const IntRect&, bool scrollToAnchor = false, const ScrollAlignment& alignX = gAlignCenterIfNeeded, const ScrollAlignment& alignY = gAlignCenterIfNeeded); 259 260 IntRect getRectToExpose(const IntRect& visibleRect, const IntRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY); 261 262 void setHasHorizontalScrollbar(bool); 263 void setHasVerticalScrollbar(bool); 264 265 PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation); 266 void destroyScrollbar(ScrollbarOrientation); 267 horizontalScrollbar()268 Scrollbar* horizontalScrollbar() const { return m_hBar.get(); } verticalScrollbar()269 Scrollbar* verticalScrollbar() const { return m_vBar.get(); } 270 271 int verticalScrollbarWidth() const; 272 int horizontalScrollbarHeight() const; 273 274 void positionOverflowControls(int tx, int ty); 275 bool isPointInResizeControl(const IntPoint& absolutePoint) const; 276 bool hitTestOverflowControls(HitTestResult&); 277 IntSize offsetFromResizeCorner(const IntPoint& absolutePoint) const; 278 279 void paintOverflowControls(GraphicsContext*, int tx, int ty, const IntRect& damageRect); 280 void paintScrollCorner(GraphicsContext*, int tx, int ty, const IntRect& damageRect); 281 void paintResizer(GraphicsContext*, int tx, int ty, const IntRect& damageRect); 282 283 void updateScrollInfoAfterLayout(); 284 285 bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f); 286 void autoscroll(); 287 288 void resize(const PlatformMouseEvent&, const IntSize&); inResizeMode()289 bool inResizeMode() const { return m_inResizeMode; } setInResizeMode(bool b)290 void setInResizeMode(bool b) { m_inResizeMode = b; } 291 292 void updateLayerPosition(); 293 void updateLayerPositions(bool doFullRepaint = false, bool checkForRepaint = true); 294 295 void updateTransform(); 296 relativePositionOffset(int & relX,int & relY)297 void relativePositionOffset(int& relX, int& relY) const { relX += m_relX; relY += m_relY; } relativePositionOffset()298 IntSize relativePositionOffset() const { return IntSize(m_relX, m_relY); } 299 300 void clearClipRectsIncludingDescendants(); 301 void clearClipRects(); 302 303 // Get the enclosing stacking context for this layer. A stacking context is a layer 304 // that has a non-auto z-index. 305 RenderLayer* stackingContext() const; isStackingContext()306 bool isStackingContext() const { return !hasAutoZIndex() || renderer()->isRenderView(); } 307 308 void dirtyZOrderLists(); 309 void dirtyStackingContextZOrderLists(); 310 void updateZOrderLists(); posZOrderList()311 Vector<RenderLayer*>* posZOrderList() const { return m_posZOrderList; } negZOrderList()312 Vector<RenderLayer*>* negZOrderList() const { return m_negZOrderList; } 313 314 void dirtyOverflowList(); 315 void updateOverflowList(); overflowList()316 Vector<RenderLayer*>* overflowList() const { return m_overflowList; } 317 hasVisibleContent()318 bool hasVisibleContent() const { return m_hasVisibleContent; } 319 void setHasVisibleContent(bool); 320 void dirtyVisibleContentStatus(); 321 322 // Gets the nearest enclosing positioned ancestor layer (also includes 323 // the <html> layer and the root layer). 324 RenderLayer* enclosingPositionedAncestor() const; 325 326 void convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int& y) const; 327 hasAutoZIndex()328 bool hasAutoZIndex() const { return renderer()->style()->hasAutoZIndex(); } zIndex()329 int zIndex() const { return renderer()->style()->zIndex(); } 330 331 // The two main functions that use the layer system. The paint method 332 // paints the layers that intersect the damage rect from back to 333 // front. The hitTest method looks for mouse events by walking 334 // layers that intersect the point from front to back. 335 void paint(GraphicsContext*, const IntRect& damageRect, PaintRestriction = PaintRestrictionNone, RenderObject* paintingRoot = 0); 336 bool hitTest(const HitTestRequest&, HitTestResult&); 337 338 // This method figures out our layerBounds in coordinates relative to 339 // |rootLayer}. It also computes our background and foreground clip rects 340 // for painting/event handling. 341 void calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds, 342 IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects = false) const; 343 344 // Compute and cache clip rects computed with the given layer as the root 345 void updateClipRects(const RenderLayer* rootLayer); 346 // Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors 347 // (rather than computing them all from scratch up the parent chain). 348 void calculateClipRects(const RenderLayer* rootLayer, ClipRects&, bool useCached = false) const; clipRects()349 ClipRects* clipRects() const { return m_clipRects; } 350 351 IntRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space. 352 IntRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space. 353 354 bool intersectsDamageRect(const IntRect& layerBounds, const IntRect& damageRect, const RenderLayer* rootLayer) const; 355 356 // Returns a bounding box for this layer only. 357 IntRect boundingBox(const RenderLayer* rootLayer) const; 358 359 void updateHoverActiveState(const HitTestRequest&, HitTestResult&); 360 repaintRect()361 IntRect repaintRect() const { return m_repaintRect; } 362 void setNeedsFullRepaint(bool f = true) { m_needsFullRepaint = f; } 363 staticX()364 int staticX() const { return m_staticX; } staticY()365 int staticY() const { return m_staticY; } setStaticX(int staticX)366 void setStaticX(int staticX) { m_staticX = staticX; } setStaticY(int staticY)367 void setStaticY(int staticY) { m_staticY = staticY; } 368 hasTransform()369 bool hasTransform() const { return renderer()->hasTransform(); } transform()370 TransformationMatrix* transform() const { return m_transform.get(); } 371 372 void destroy(RenderArena*); 373 374 // Overloaded new operator. Derived classes must override operator new 375 // in order to allocate out of the RenderArena. 376 void* operator new(size_t, RenderArena*) throw(); 377 378 // Overridden to prevent the normal delete from being called. 379 void operator delete(void*, size_t); 380 381 private: 382 // The normal operator new is disallowed on all render objects. 383 void* operator new(size_t) throw(); 384 385 private: setNextSibling(RenderLayer * next)386 void setNextSibling(RenderLayer* next) { m_next = next; } setPreviousSibling(RenderLayer * prev)387 void setPreviousSibling(RenderLayer* prev) { m_previous = prev; } setParent(RenderLayer * parent)388 void setParent(RenderLayer* parent) { m_parent = parent; } setFirstChild(RenderLayer * first)389 void setFirstChild(RenderLayer* first) { m_first = first; } setLastChild(RenderLayer * last)390 void setLastChild(RenderLayer* last) { m_last = last; } 391 392 void collectLayers(Vector<RenderLayer*>*&, Vector<RenderLayer*>*&); 393 394 void paintLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect, 395 bool haveTransparency, PaintRestriction, RenderObject* paintingRoot, 396 bool appliedTransform = false, bool temporaryClipRects = false); 397 RenderLayer* hitTestLayer(RenderLayer* rootLayer, const HitTestRequest&, HitTestResult&, const IntRect& hitTestRect, const IntPoint& hitTestPoint, bool appliedTransform = false); 398 void computeScrollDimensions(bool* needHBar = 0, bool* needVBar = 0); 399 400 bool shouldBeOverflowOnly() const; 401 402 virtual void valueChanged(Scrollbar*); 403 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&); 404 virtual bool isActive() const; 405 virtual bool scrollbarCornerPresent() const; 406 407 void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow); 408 409 void childVisibilityChanged(bool newVisibility); 410 void dirtyVisibleDescendantStatus(); 411 void updateVisibilityStatus(); 412 413 Node* enclosingElement() const; 414 415 void createReflection(); 416 void updateReflectionStyle(); paintingInsideReflection()417 bool paintingInsideReflection() const { return m_paintingInsideReflection; } 418 419 RenderLayer* enclosingTransformedAncestor() const; 420 421 // Convert a point in absolute coords into layer coords, taking transforms into account 422 IntPoint absoluteToContents(const IntPoint&) const; 423 424 void updateScrollCornerStyle(); 425 void updateResizerStyle(); 426 427 protected: 428 RenderBox* m_renderer; 429 430 RenderLayer* m_parent; 431 RenderLayer* m_previous; 432 RenderLayer* m_next; 433 RenderLayer* m_first; 434 RenderLayer* m_last; 435 436 IntRect m_repaintRect; // Cached repaint rects. Used by layout. 437 IntRect m_outlineBox; 438 439 // Our current relative position offset. 440 int m_relX; 441 int m_relY; 442 443 // Our (x,y) coordinates are in our parent layer's coordinate space. 444 int m_x; 445 int m_y; 446 447 // The layer's width/height 448 int m_width; 449 int m_height; 450 451 // Our scroll offsets if the view is scrolled. 452 int m_scrollX; 453 int m_scrollY; 454 int m_scrollOriginX; // only non-zero for rtl content 455 int m_scrollLeftOverflow; // only non-zero for rtl content 456 457 // The width/height of our scrolled area. 458 int m_scrollWidth; 459 int m_scrollHeight; 460 461 // For layers with overflow, we have a pair of scrollbars. 462 RefPtr<Scrollbar> m_hBar; 463 RefPtr<Scrollbar> m_vBar; 464 465 // Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop. 466 bool m_inResizeMode; 467 468 // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the 469 // descendant layers within the stacking context that have z-indices of 0 or greater 470 // (auto will count as 0). m_negZOrderList holds descendants within our stacking context with negative 471 // z-indices. 472 Vector<RenderLayer*>* m_posZOrderList; 473 Vector<RenderLayer*>* m_negZOrderList; 474 475 // This list contains child layers that cannot create stacking contexts. For now it is just 476 // overflow layers, but that may change in the future. 477 Vector<RenderLayer*>* m_overflowList; 478 479 ClipRects* m_clipRects; // Cached clip rects used when painting and hit testing. 480 #ifndef NDEBUG 481 const RenderLayer* m_clipRectsRoot; // Root layer used to compute clip rects. 482 #endif 483 484 bool m_scrollDimensionsDirty : 1; 485 bool m_zOrderListsDirty : 1; 486 bool m_overflowListDirty: 1; 487 bool m_isOverflowOnly : 1; 488 489 bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether 490 // we ended up painting this layer or any descendants (and therefore need to 491 // blend). 492 bool m_paintingInsideReflection : 1; // A state bit tracking if we are painting inside a replica. 493 bool m_inOverflowRelayout : 1; 494 bool m_needsFullRepaint : 1; 495 496 bool m_overflowStatusDirty : 1; 497 bool m_horizontalOverflow : 1; 498 bool m_verticalOverflow : 1; 499 bool m_visibleContentStatusDirty : 1; 500 bool m_hasVisibleContent : 1; 501 bool m_visibleDescendantStatusDirty : 1; 502 bool m_hasVisibleDescendant : 1; 503 504 RenderMarquee* m_marquee; // Used by layers with overflow:marquee 505 506 // Cached normal flow values for absolute positioned elements with static left/top values. 507 int m_staticX; 508 int m_staticY; 509 510 OwnPtr<TransformationMatrix> m_transform; 511 512 // May ultimately be extended to many replicas (with their own paint order). 513 RenderReplica* m_reflection; 514 515 // Renderers to hold our custom scroll corner and resizer. 516 RenderScrollbarPart* m_scrollCorner; 517 RenderScrollbarPart* m_resizer; 518 }; 519 520 } // namespace WebCore 521 522 #endif // RenderLayer_h 523