1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef DISPLAYLISTCLIPSTATE_H_
7 #define DISPLAYLISTCLIPSTATE_H_
9 #include "DisplayItemClip.h"
11 #include "mozilla/DebugOnly.h"
14 class nsDisplayListBuilder
;
19 * All clip coordinates are in appunits relative to the reference frame
20 * for the display item we're building.
22 class DisplayListClipState
{
24 DisplayListClipState()
25 : mClipContentDescendants(nullptr)
26 , mClipContainingBlockDescendants(nullptr)
27 , mCurrentCombinedClip(nullptr)
31 * Returns intersection of mClipContainingBlockDescendants and
32 * mClipContentDescendants, allocated on aBuilder's arena.
34 const DisplayItemClip
* GetCurrentCombinedClip(nsDisplayListBuilder
* aBuilder
);
36 const DisplayItemClip
* GetClipForContainingBlockDescendants() const
38 return mClipContainingBlockDescendants
;
40 const DisplayItemClip
* GetClipForContentDescendants() const
42 return mClipContentDescendants
;
45 class AutoSaveRestore
;
46 friend class AutoSaveRestore
;
48 class AutoClipContainingBlockDescendantsToContentBox
;
49 friend class AutoClipContainingBlockDescendantsToContentBox
;
51 class AutoClipMultiple
;
52 friend class AutoClipMultiple
;
55 ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT
= 0x01
59 void SetClipForContainingBlockDescendants(const DisplayItemClip
* aClip
)
61 mClipContainingBlockDescendants
= aClip
;
62 mCurrentCombinedClip
= nullptr;
67 mClipContentDescendants
= nullptr;
68 mClipContainingBlockDescendants
= nullptr;
69 mCurrentCombinedClip
= nullptr;
73 * Intersects the given clip rect (with optional aRadii) with the current
74 * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
75 * the result, stored in aClipOnStack.
77 void ClipContainingBlockDescendants(const nsRect
& aRect
,
78 const nscoord
* aRadii
,
79 DisplayItemClip
& aClipOnStack
);
81 void ClipContentDescendants(const nsRect
& aRect
,
82 const nscoord
* aRadii
,
83 DisplayItemClip
& aClipOnStack
);
84 void ClipContentDescendants(const nsRect
& aRect
,
85 const nsRect
& aRoundedRect
,
86 const nscoord
* aRadii
,
87 DisplayItemClip
& aClipOnStack
);
90 * Clips containing-block descendants to the frame's content-box,
91 * taking border-radius into account.
92 * If aFlags contains ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT then
93 * we assume display items will not draw outside the content rect, so
94 * clipping is only required if there is a border-radius. This is an
95 * optimization to reduce the amount of clipping required.
97 void ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder
* aBuilder
,
99 DisplayItemClip
& aClipOnStack
,
103 * All content descendants (i.e. following placeholder frames to their
104 * out-of-flows if necessary) should be clipped by mClipContentDescendants.
105 * Null if no clipping applies.
107 const DisplayItemClip
* mClipContentDescendants
;
109 * All containing-block descendants (i.e. frame descendants), including
110 * display items for the current frame, should be clipped by
111 * mClipContainingBlockDescendants.
112 * Null if no clipping applies.
114 const DisplayItemClip
* mClipContainingBlockDescendants
;
116 * The intersection of mClipContentDescendants and
117 * mClipContainingBlockDescendants.
118 * Allocated in the nsDisplayListBuilder arena. Null if none has been
119 * allocated or both mClipContentDescendants and mClipContainingBlockDescendants
122 const DisplayItemClip
* mCurrentCombinedClip
;
126 * A class to automatically save and restore the current clip state. Also
127 * offers methods for modifying the clip state. Only one modification is allowed
128 * to be in scope at a time using one of these objects; multiple modifications
129 * require nested objects. The interface is written this way to prevent
130 * dangling pointers to DisplayItemClips.
132 class DisplayListClipState::AutoSaveRestore
{
134 explicit AutoSaveRestore(nsDisplayListBuilder
* aBuilder
);
137 mState
= mSavedState
;
142 mState
= mSavedState
;
147 NS_ASSERTION(!mRestored
, "Already restored!");
153 * Intersects the given clip rect (with optional aRadii) with the current
154 * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
155 * the result, stored in aClipOnStack.
157 void ClipContainingBlockDescendants(const nsRect
& aRect
,
158 const nscoord
* aRadii
= nullptr)
160 NS_ASSERTION(!mRestored
, "Already restored!");
161 NS_ASSERTION(!mClipUsed
, "mClip already used");
163 mState
.ClipContainingBlockDescendants(aRect
, aRadii
, mClip
);
166 void ClipContentDescendants(const nsRect
& aRect
,
167 const nscoord
* aRadii
= nullptr)
169 NS_ASSERTION(!mRestored
, "Already restored!");
170 NS_ASSERTION(!mClipUsed
, "mClip already used");
172 mState
.ClipContentDescendants(aRect
, aRadii
, mClip
);
175 void ClipContentDescendants(const nsRect
& aRect
,
176 const nsRect
& aRoundedRect
,
177 const nscoord
* aRadii
= nullptr)
179 NS_ASSERTION(!mRestored
, "Already restored!");
180 NS_ASSERTION(!mClipUsed
, "mClip already used");
182 mState
.ClipContentDescendants(aRect
, aRoundedRect
, aRadii
, mClip
);
186 * Clips containing-block descendants to the frame's content-box,
187 * taking border-radius into account.
188 * If aFlags contains ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT then
189 * we assume display items will not draw outside the content rect, so
190 * clipping is only required if there is a border-radius. This is an
191 * optimization to reduce the amount of clipping required.
193 void ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder
* aBuilder
,
197 NS_ASSERTION(!mRestored
, "Already restored!");
198 NS_ASSERTION(!mClipUsed
, "mClip already used");
200 mState
.ClipContainingBlockDescendantsToContentBox(aBuilder
, aFrame
, mClip
, aFlags
);
204 DisplayListClipState
& mState
;
205 DisplayListClipState mSavedState
;
206 DisplayItemClip mClip
;
207 DebugOnly
<bool> mClipUsed
;
208 DebugOnly
<bool> mRestored
;
211 class DisplayListClipState::AutoClipContainingBlockDescendantsToContentBox
: public AutoSaveRestore
{
213 AutoClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder
* aBuilder
,
216 : AutoSaveRestore(aBuilder
)
219 mState
.ClipContainingBlockDescendantsToContentBox(aBuilder
, aFrame
, mClip
, aFlags
);
224 * Do not use this outside of nsFrame::BuildDisplayListForChild, use
225 * multiple AutoSaveRestores instead. We provide this class just to ensure
226 * BuildDisplayListForChild is as efficient as possible.
228 class DisplayListClipState::AutoClipMultiple
: public AutoSaveRestore
{
230 explicit AutoClipMultiple(nsDisplayListBuilder
* aBuilder
)
231 : AutoSaveRestore(aBuilder
)
232 , mExtraClipUsed(false)
236 * *aClip must survive longer than this object. Be careful!!!
238 void SetClipForContainingBlockDescendants(const DisplayItemClip
* aClip
)
240 mState
.SetClipForContainingBlockDescendants(aClip
);
244 * Intersects the given clip rect (with optional aRadii) with the current
245 * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
246 * the result, stored in aClipOnStack.
248 void ClipContainingBlockDescendantsExtra(const nsRect
& aRect
,
249 const nscoord
* aRadii
)
251 NS_ASSERTION(!mRestored
, "Already restored!");
252 NS_ASSERTION(!mExtraClipUsed
, "mExtraClip already used");
253 mExtraClipUsed
= true;
254 mState
.ClipContainingBlockDescendants(aRect
, aRadii
, mExtraClip
);
258 DisplayItemClip mExtraClip
;
259 DebugOnly
<bool> mExtraClipUsed
;
264 #endif /* DISPLAYLISTCLIPSTATE_H_ */