1 /* 2 * Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef ClipRect_h 27 #define ClipRect_h 28 29 #include "platform/geometry/LayoutRect.h" 30 31 #include "wtf/Vector.h" 32 33 #ifndef NDEBUG 34 #include "core/rendering/RenderBox.h" // For OverlayScrollbarSizeRelevancy. 35 #endif 36 37 namespace WebCore { 38 39 class RenderLayer; 40 class HitTestLocation; 41 42 class ClipRect { 43 public: 44 ClipRect() 45 : m_hasRadius(false) 46 { } 47 48 ClipRect(const LayoutRect& rect) 49 : m_rect(rect) 50 , m_hasRadius(false) 51 { } 52 53 const LayoutRect& rect() const { return m_rect; } 54 void setRect(const LayoutRect& rect) { m_rect = rect; } 55 56 bool hasRadius() const { return m_hasRadius; } 57 void setHasRadius(bool hasRadius) { m_hasRadius = hasRadius; } 58 59 bool operator==(const ClipRect& other) const { return rect() == other.rect() && hasRadius() == other.hasRadius(); } 60 bool operator!=(const ClipRect& other) const { return rect() != other.rect() || hasRadius() != other.hasRadius(); } 61 bool operator!=(const LayoutRect& otherRect) const { return rect() != otherRect; } 62 63 void intersect(const LayoutRect& other) { m_rect.intersect(other); } 64 void intersect(const ClipRect& other) 65 { 66 m_rect.intersect(other.rect()); 67 if (other.hasRadius()) 68 m_hasRadius = true; 69 } 70 void move(LayoutUnit x, LayoutUnit y) { m_rect.move(x, y); } 71 void move(const LayoutSize& size) { m_rect.move(size); } 72 void moveBy(const LayoutPoint& point) { m_rect.moveBy(point); } 73 74 bool isEmpty() const { return m_rect.isEmpty(); } 75 bool intersects(const LayoutRect& rect) const { return m_rect.intersects(rect); } 76 bool intersects(const HitTestLocation&) const; 77 78 private: 79 LayoutRect m_rect; 80 bool m_hasRadius; 81 }; 82 83 inline ClipRect intersection(const ClipRect& a, const ClipRect& b) 84 { 85 ClipRect c = a; 86 c.intersect(b); 87 return c; 88 } 89 90 class ClipRects { 91 WTF_MAKE_FAST_ALLOCATED; 92 public: 93 static PassRefPtr<ClipRects> create() 94 { 95 return adoptRef(new ClipRects); 96 } 97 98 static PassRefPtr<ClipRects> create(const ClipRects& other) 99 { 100 return adoptRef(new ClipRects(other)); 101 } 102 103 ClipRects() 104 : m_refCnt(1) 105 , m_fixed(0) 106 { 107 } 108 109 void reset(const LayoutRect& r) 110 { 111 m_overflowClipRect = r; 112 m_fixedClipRect = r; 113 m_posClipRect = r; 114 m_fixed = 0; 115 } 116 117 const ClipRect& overflowClipRect() const { return m_overflowClipRect; } 118 void setOverflowClipRect(const ClipRect& r) { m_overflowClipRect = r; } 119 120 const ClipRect& fixedClipRect() const { return m_fixedClipRect; } 121 void setFixedClipRect(const ClipRect&r) { m_fixedClipRect = r; } 122 123 const ClipRect& posClipRect() const { return m_posClipRect; } 124 void setPosClipRect(const ClipRect& r) { m_posClipRect = r; } 125 126 bool fixed() const { return static_cast<bool>(m_fixed); } 127 void setFixed(bool fixed) { m_fixed = fixed ? 1 : 0; } 128 129 void ref() { m_refCnt++; } 130 void deref() 131 { 132 if (!--m_refCnt) 133 delete this; 134 } 135 136 bool operator==(const ClipRects& other) const 137 { 138 return m_overflowClipRect == other.overflowClipRect() 139 && m_fixedClipRect == other.fixedClipRect() 140 && m_posClipRect == other.posClipRect() 141 && fixed() == other.fixed(); 142 } 143 144 ClipRects& operator=(const ClipRects& other) 145 { 146 m_overflowClipRect = other.overflowClipRect(); 147 m_fixedClipRect = other.fixedClipRect(); 148 m_posClipRect = other.posClipRect(); 149 m_fixed = other.fixed(); 150 return *this; 151 } 152 153 private: 154 ClipRects(const LayoutRect& r) 155 : m_overflowClipRect(r) 156 , m_fixedClipRect(r) 157 , m_posClipRect(r) 158 , m_refCnt(1) 159 , m_fixed(0) 160 { 161 } 162 163 ClipRects(const ClipRects& other) 164 : m_overflowClipRect(other.overflowClipRect()) 165 , m_fixedClipRect(other.fixedClipRect()) 166 , m_posClipRect(other.posClipRect()) 167 , m_refCnt(1) 168 , m_fixed(other.fixed()) 169 { 170 } 171 172 ClipRect m_overflowClipRect; 173 ClipRect m_fixedClipRect; 174 ClipRect m_posClipRect; 175 unsigned m_refCnt : 31; 176 unsigned m_fixed : 1; 177 }; 178 179 enum ClipRectsType { 180 PaintingClipRects, // Relative to painting ancestor. Used for painting. 181 RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing. 182 AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing. 183 NumCachedClipRectsTypes, 184 AllClipRectTypes, 185 TemporaryClipRects 186 }; 187 188 enum ShouldRespectOverflowClip { 189 IgnoreOverflowClip, 190 RespectOverflowClip 191 }; 192 193 struct ClipRectsCache { 194 WTF_MAKE_FAST_ALLOCATED; 195 public: 196 ClipRectsCache() 197 { 198 #ifndef NDEBUG 199 for (int i = 0; i < NumCachedClipRectsTypes; ++i) { 200 m_clipRectsRoot[i] = 0; 201 m_scrollbarRelevancy[i] = IgnoreOverlayScrollbarSize; 202 } 203 #endif 204 } 205 206 PassRefPtr<ClipRects> getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)]; } 207 void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, PassRefPtr<ClipRects> clipRects) { m_clipRects[getIndex(clipRectsType, respectOverflow)] = clipRects; } 208 209 #ifndef NDEBUG 210 const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes]; 211 OverlayScrollbarSizeRelevancy m_scrollbarRelevancy[NumCachedClipRectsTypes]; 212 #endif 213 214 private: 215 int getIndex(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) 216 { 217 int index = static_cast<int>(clipRectsType); 218 if (respectOverflow == RespectOverflowClip) 219 index += static_cast<int>(NumCachedClipRectsTypes); 220 return index; 221 } 222 223 RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes * 2]; 224 }; 225 226 struct LayerFragment { 227 public: 228 LayerFragment() 229 : shouldPaintContent(false) 230 { } 231 232 void setRects(const LayoutRect& bounds, const ClipRect& background, const ClipRect& foreground, const ClipRect& outline) 233 { 234 layerBounds = bounds; 235 backgroundRect = background; 236 foregroundRect = foreground; 237 outlineRect = outline; 238 } 239 240 void moveBy(const LayoutPoint& offset) 241 { 242 layerBounds.moveBy(offset); 243 backgroundRect.moveBy(offset); 244 foregroundRect.moveBy(offset); 245 outlineRect.moveBy(offset); 246 paginationClip.moveBy(offset); 247 } 248 249 void intersect(const LayoutRect& rect) 250 { 251 backgroundRect.intersect(rect); 252 foregroundRect.intersect(rect); 253 outlineRect.intersect(rect); 254 } 255 256 bool shouldPaintContent; 257 LayoutRect layerBounds; 258 ClipRect backgroundRect; 259 ClipRect foregroundRect; 260 ClipRect outlineRect; 261 262 // Unique to paginated fragments. The physical translation to apply to shift the layer when painting/hit-testing. 263 LayoutPoint paginationOffset; 264 265 // Also unique to paginated fragments. An additional clip that applies to the layer. It is in layer-local 266 // (physical) coordinates. 267 LayoutRect paginationClip; 268 }; 269 270 typedef Vector<LayerFragment, 1> LayerFragments; 271 272 } // namespace WebCore 273 274 #endif // ClipRect_h 275