• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ClipRect()44     ClipRect()
45         : m_hasRadius(false)
46     { }
47 
ClipRect(const LayoutRect & rect)48     ClipRect(const LayoutRect& rect)
49         : m_rect(rect)
50         , m_hasRadius(false)
51     { }
52 
rect()53     const LayoutRect& rect() const { return m_rect; }
setRect(const LayoutRect & rect)54     void setRect(const LayoutRect& rect) { m_rect = rect; }
55 
hasRadius()56     bool hasRadius() const { return m_hasRadius; }
setHasRadius(bool 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 
intersect(const LayoutRect & other)63     void intersect(const LayoutRect& other) { m_rect.intersect(other); }
intersect(const ClipRect & other)64     void intersect(const ClipRect& other)
65     {
66         m_rect.intersect(other.rect());
67         if (other.hasRadius())
68             m_hasRadius = true;
69     }
move(LayoutUnit x,LayoutUnit y)70     void move(LayoutUnit x, LayoutUnit y) { m_rect.move(x, y); }
move(const LayoutSize & size)71     void move(const LayoutSize& size) { m_rect.move(size); }
moveBy(const LayoutPoint & point)72     void moveBy(const LayoutPoint& point) { m_rect.moveBy(point); }
73 
isEmpty()74     bool isEmpty() const { return m_rect.isEmpty(); }
intersects(const LayoutRect & rect)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 
intersection(const ClipRect & a,const ClipRect & b)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:
create()93     static PassRefPtr<ClipRects> create()
94     {
95         return adoptRef(new ClipRects);
96     }
97 
create(const ClipRects & other)98     static PassRefPtr<ClipRects> create(const ClipRects& other)
99     {
100         return adoptRef(new ClipRects(other));
101     }
102 
ClipRects()103     ClipRects()
104         : m_refCnt(1)
105         , m_fixed(0)
106     {
107     }
108 
reset(const LayoutRect & r)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 
overflowClipRect()117     const ClipRect& overflowClipRect() const { return m_overflowClipRect; }
setOverflowClipRect(const ClipRect & r)118     void setOverflowClipRect(const ClipRect& r) { m_overflowClipRect = r; }
119 
fixedClipRect()120     const ClipRect& fixedClipRect() const { return m_fixedClipRect; }
setFixedClipRect(const ClipRect & r)121     void setFixedClipRect(const ClipRect&r) { m_fixedClipRect = r; }
122 
posClipRect()123     const ClipRect& posClipRect() const { return m_posClipRect; }
setPosClipRect(const ClipRect & r)124     void setPosClipRect(const ClipRect& r) { m_posClipRect = r; }
125 
fixed()126     bool fixed() const { return static_cast<bool>(m_fixed); }
setFixed(bool fixed)127     void setFixed(bool fixed) { m_fixed = fixed ? 1 : 0; }
128 
ref()129     void ref() { m_refCnt++; }
deref()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:
ClipRects(const LayoutRect & r)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 
ClipRects(const ClipRects & other)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:
ClipRectsCacheClipRectsCache196     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 
getClipRectsClipRectsCache206     PassRefPtr<ClipRects> getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)]; }
setClipRectsClipRectsCache207     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:
getIndexClipRectsCache215     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:
LayerFragmentLayerFragment228     LayerFragment()
229         : shouldPaintContent(false)
230     { }
231 
setRectsLayerFragment232     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 
moveByLayerFragment240     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 
intersectLayerFragment249     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