• 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     CompositingClipRects, // Relative to the compositing ancestor. Used for updating graphics layer geometry.
183     AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing.
184     NumCachedClipRectsTypes,
185     AllClipRectTypes,
186     TemporaryClipRects
187 };
188 
189 enum ShouldRespectOverflowClip {
190     IgnoreOverflowClip,
191     RespectOverflowClip
192 };
193 
194 struct ClipRectsCache {
195     WTF_MAKE_FAST_ALLOCATED;
196 public:
ClipRectsCacheClipRectsCache197     ClipRectsCache()
198     {
199         for (int i = 0; i < NumCachedClipRectsTypes; ++i) {
200             m_clipRectsRoot[i] = 0;
201 #ifndef NDEBUG
202             m_scrollbarRelevancy[i] = IgnoreOverlayScrollbarSize;
203 #endif
204         }
205     }
206 
getClipRectsClipRectsCache207     PassRefPtr<ClipRects> getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)]; }
setClipRectsClipRectsCache208     void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, PassRefPtr<ClipRects> clipRects, const RenderLayer* root)
209     {
210         m_clipRects[getIndex(clipRectsType, respectOverflow)] = clipRects;
211         m_clipRectsRoot[clipRectsType] = root;
212     }
213 
clipRectsRootClipRectsCache214     const RenderLayer* clipRectsRoot(ClipRectsType clipRectsType) const { return m_clipRectsRoot[clipRectsType]; }
215 
216 #ifndef NDEBUG
217     OverlayScrollbarSizeRelevancy m_scrollbarRelevancy[NumCachedClipRectsTypes];
218 #endif
219 
220 private:
getIndexClipRectsCache221     int getIndex(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow)
222     {
223         int index = static_cast<int>(clipRectsType);
224         if (respectOverflow == RespectOverflowClip)
225             index += static_cast<int>(NumCachedClipRectsTypes);
226         return index;
227     }
228 
229     const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
230     RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes * 2];
231 };
232 
233 struct LayerFragment {
234 public:
LayerFragmentLayerFragment235     LayerFragment()
236         : shouldPaintContent(false)
237     { }
238 
setRectsLayerFragment239     void setRects(const LayoutRect& bounds, const ClipRect& background, const ClipRect& foreground, const ClipRect& outline)
240     {
241         layerBounds = bounds;
242         backgroundRect = background;
243         foregroundRect = foreground;
244         outlineRect = outline;
245     }
246 
moveByLayerFragment247     void moveBy(const LayoutPoint& offset)
248     {
249         layerBounds.moveBy(offset);
250         backgroundRect.moveBy(offset);
251         foregroundRect.moveBy(offset);
252         outlineRect.moveBy(offset);
253         paginationClip.moveBy(offset);
254     }
255 
intersectLayerFragment256     void intersect(const LayoutRect& rect)
257     {
258         backgroundRect.intersect(rect);
259         foregroundRect.intersect(rect);
260         outlineRect.intersect(rect);
261     }
262 
263     bool shouldPaintContent;
264     LayoutRect layerBounds;
265     ClipRect backgroundRect;
266     ClipRect foregroundRect;
267     ClipRect outlineRect;
268 
269     // Unique to paginated fragments. The physical translation to apply to shift the layer when painting/hit-testing.
270     LayoutPoint paginationOffset;
271 
272     // Also unique to paginated fragments. An additional clip that applies to the layer. It is in layer-local
273     // (physical) coordinates.
274     LayoutRect paginationClip;
275 };
276 
277 typedef Vector<LayerFragment, 1> LayerFragments;
278 
279 } // namespace WebCore
280 
281 #endif // ClipRect_h
282