layout/base/DisplayListClipState.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef DISPLAYLISTCLIPSTATE_H_
michael@0 7 #define DISPLAYLISTCLIPSTATE_H_
michael@0 8
michael@0 9 #include "DisplayItemClip.h"
michael@0 10
michael@0 11 #include "mozilla/DebugOnly.h"
michael@0 12
michael@0 13 class nsIFrame;
michael@0 14 class nsDisplayListBuilder;
michael@0 15
michael@0 16 namespace mozilla {
michael@0 17
michael@0 18 /**
michael@0 19 * All clip coordinates are in appunits relative to the reference frame
michael@0 20 * for the display item we're building.
michael@0 21 */
michael@0 22 class DisplayListClipState {
michael@0 23 public:
michael@0 24 DisplayListClipState()
michael@0 25 : mClipContentDescendants(nullptr)
michael@0 26 , mClipContainingBlockDescendants(nullptr)
michael@0 27 , mCurrentCombinedClip(nullptr)
michael@0 28 {}
michael@0 29
michael@0 30 /**
michael@0 31 * Returns intersection of mClipContainingBlockDescendants and
michael@0 32 * mClipContentDescendants, allocated on aBuilder's arena.
michael@0 33 */
michael@0 34 const DisplayItemClip* GetCurrentCombinedClip(nsDisplayListBuilder* aBuilder);
michael@0 35
michael@0 36 const DisplayItemClip* GetClipForContainingBlockDescendants() const
michael@0 37 {
michael@0 38 return mClipContainingBlockDescendants;
michael@0 39 }
michael@0 40 const DisplayItemClip* GetClipForContentDescendants() const
michael@0 41 {
michael@0 42 return mClipContentDescendants;
michael@0 43 }
michael@0 44
michael@0 45 class AutoSaveRestore;
michael@0 46 friend class AutoSaveRestore;
michael@0 47
michael@0 48 class AutoClipContainingBlockDescendantsToContentBox;
michael@0 49 friend class AutoClipContainingBlockDescendantsToContentBox;
michael@0 50
michael@0 51 class AutoClipMultiple;
michael@0 52 friend class AutoClipMultiple;
michael@0 53
michael@0 54 enum {
michael@0 55 ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT = 0x01
michael@0 56 };
michael@0 57
michael@0 58 private:
michael@0 59 void SetClipForContainingBlockDescendants(const DisplayItemClip* aClip)
michael@0 60 {
michael@0 61 mClipContainingBlockDescendants = aClip;
michael@0 62 mCurrentCombinedClip = nullptr;
michael@0 63 }
michael@0 64
michael@0 65 void Clear()
michael@0 66 {
michael@0 67 mClipContentDescendants = nullptr;
michael@0 68 mClipContainingBlockDescendants = nullptr;
michael@0 69 mCurrentCombinedClip = nullptr;
michael@0 70 }
michael@0 71
michael@0 72 /**
michael@0 73 * Intersects the given clip rect (with optional aRadii) with the current
michael@0 74 * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
michael@0 75 * the result, stored in aClipOnStack.
michael@0 76 */
michael@0 77 void ClipContainingBlockDescendants(const nsRect& aRect,
michael@0 78 const nscoord* aRadii,
michael@0 79 DisplayItemClip& aClipOnStack);
michael@0 80
michael@0 81 void ClipContentDescendants(const nsRect& aRect,
michael@0 82 const nscoord* aRadii,
michael@0 83 DisplayItemClip& aClipOnStack);
michael@0 84
michael@0 85 /**
michael@0 86 * Clips containing-block descendants to the frame's content-box,
michael@0 87 * taking border-radius into account.
michael@0 88 * If aFlags contains ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT then
michael@0 89 * we assume display items will not draw outside the content rect, so
michael@0 90 * clipping is only required if there is a border-radius. This is an
michael@0 91 * optimization to reduce the amount of clipping required.
michael@0 92 */
michael@0 93 void ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
michael@0 94 nsIFrame* aFrame,
michael@0 95 DisplayItemClip& aClipOnStack,
michael@0 96 uint32_t aFlags);
michael@0 97
michael@0 98 /**
michael@0 99 * All content descendants (i.e. following placeholder frames to their
michael@0 100 * out-of-flows if necessary) should be clipped by mClipContentDescendants.
michael@0 101 * Null if no clipping applies.
michael@0 102 */
michael@0 103 const DisplayItemClip* mClipContentDescendants;
michael@0 104 /**
michael@0 105 * All containing-block descendants (i.e. frame descendants), including
michael@0 106 * display items for the current frame, should be clipped by
michael@0 107 * mClipContainingBlockDescendants.
michael@0 108 * Null if no clipping applies.
michael@0 109 */
michael@0 110 const DisplayItemClip* mClipContainingBlockDescendants;
michael@0 111 /**
michael@0 112 * The intersection of mClipContentDescendants and
michael@0 113 * mClipContainingBlockDescendants.
michael@0 114 * Allocated in the nsDisplayListBuilder arena. Null if none has been
michael@0 115 * allocated or both mClipContentDescendants and mClipContainingBlockDescendants
michael@0 116 * are null.
michael@0 117 */
michael@0 118 const DisplayItemClip* mCurrentCombinedClip;
michael@0 119 };
michael@0 120
michael@0 121 /**
michael@0 122 * A class to automatically save and restore the current clip state. Also
michael@0 123 * offers methods for modifying the clip state. Only one modification is allowed
michael@0 124 * to be in scope at a time using one of these objects; multiple modifications
michael@0 125 * require nested objects. The interface is written this way to prevent
michael@0 126 * dangling pointers to DisplayItemClips.
michael@0 127 */
michael@0 128 class DisplayListClipState::AutoSaveRestore {
michael@0 129 public:
michael@0 130 AutoSaveRestore(nsDisplayListBuilder* aBuilder);
michael@0 131 void Restore()
michael@0 132 {
michael@0 133 mState = mSavedState;
michael@0 134 mRestored = true;
michael@0 135 }
michael@0 136 ~AutoSaveRestore()
michael@0 137 {
michael@0 138 mState = mSavedState;
michael@0 139 }
michael@0 140
michael@0 141 void Clear()
michael@0 142 {
michael@0 143 NS_ASSERTION(!mRestored, "Already restored!");
michael@0 144 mState.Clear();
michael@0 145 mClipUsed = false;
michael@0 146 }
michael@0 147
michael@0 148 /**
michael@0 149 * Intersects the given clip rect (with optional aRadii) with the current
michael@0 150 * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
michael@0 151 * the result, stored in aClipOnStack.
michael@0 152 */
michael@0 153 void ClipContainingBlockDescendants(const nsRect& aRect,
michael@0 154 const nscoord* aRadii = nullptr)
michael@0 155 {
michael@0 156 NS_ASSERTION(!mRestored, "Already restored!");
michael@0 157 NS_ASSERTION(!mClipUsed, "mClip already used");
michael@0 158 mClipUsed = true;
michael@0 159 mState.ClipContainingBlockDescendants(aRect, aRadii, mClip);
michael@0 160 }
michael@0 161
michael@0 162 void ClipContentDescendants(const nsRect& aRect,
michael@0 163 const nscoord* aRadii = nullptr)
michael@0 164 {
michael@0 165 NS_ASSERTION(!mRestored, "Already restored!");
michael@0 166 NS_ASSERTION(!mClipUsed, "mClip already used");
michael@0 167 mClipUsed = true;
michael@0 168 mState.ClipContentDescendants(aRect, aRadii, mClip);
michael@0 169 }
michael@0 170
michael@0 171 /**
michael@0 172 * Clips containing-block descendants to the frame's content-box,
michael@0 173 * taking border-radius into account.
michael@0 174 * If aFlags contains ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT then
michael@0 175 * we assume display items will not draw outside the content rect, so
michael@0 176 * clipping is only required if there is a border-radius. This is an
michael@0 177 * optimization to reduce the amount of clipping required.
michael@0 178 */
michael@0 179 void ClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
michael@0 180 nsIFrame* aFrame,
michael@0 181 uint32_t aFlags = 0)
michael@0 182 {
michael@0 183 NS_ASSERTION(!mRestored, "Already restored!");
michael@0 184 NS_ASSERTION(!mClipUsed, "mClip already used");
michael@0 185 mClipUsed = true;
michael@0 186 mState.ClipContainingBlockDescendantsToContentBox(aBuilder, aFrame, mClip, aFlags);
michael@0 187 }
michael@0 188
michael@0 189 protected:
michael@0 190 DisplayListClipState& mState;
michael@0 191 DisplayListClipState mSavedState;
michael@0 192 DisplayItemClip mClip;
michael@0 193 DebugOnly<bool> mClipUsed;
michael@0 194 DebugOnly<bool> mRestored;
michael@0 195 };
michael@0 196
michael@0 197 class DisplayListClipState::AutoClipContainingBlockDescendantsToContentBox : public AutoSaveRestore {
michael@0 198 public:
michael@0 199 AutoClipContainingBlockDescendantsToContentBox(nsDisplayListBuilder* aBuilder,
michael@0 200 nsIFrame* aFrame,
michael@0 201 uint32_t aFlags = 0)
michael@0 202 : AutoSaveRestore(aBuilder)
michael@0 203 {
michael@0 204 mClipUsed = true;
michael@0 205 mState.ClipContainingBlockDescendantsToContentBox(aBuilder, aFrame, mClip, aFlags);
michael@0 206 }
michael@0 207 };
michael@0 208
michael@0 209 /**
michael@0 210 * Do not use this outside of nsFrame::BuildDisplayListForChild, use
michael@0 211 * multiple AutoSaveRestores instead. We provide this class just to ensure
michael@0 212 * BuildDisplayListForChild is as efficient as possible.
michael@0 213 */
michael@0 214 class DisplayListClipState::AutoClipMultiple : public AutoSaveRestore {
michael@0 215 public:
michael@0 216 AutoClipMultiple(nsDisplayListBuilder* aBuilder)
michael@0 217 : AutoSaveRestore(aBuilder)
michael@0 218 , mExtraClipUsed(false)
michael@0 219 {}
michael@0 220
michael@0 221 /**
michael@0 222 * *aClip must survive longer than this object. Be careful!!!
michael@0 223 */
michael@0 224 void SetClipForContainingBlockDescendants(const DisplayItemClip* aClip)
michael@0 225 {
michael@0 226 mState.SetClipForContainingBlockDescendants(aClip);
michael@0 227 }
michael@0 228
michael@0 229 /**
michael@0 230 * Intersects the given clip rect (with optional aRadii) with the current
michael@0 231 * mClipContainingBlockDescendants and sets mClipContainingBlockDescendants to
michael@0 232 * the result, stored in aClipOnStack.
michael@0 233 */
michael@0 234 void ClipContainingBlockDescendantsExtra(const nsRect& aRect,
michael@0 235 const nscoord* aRadii)
michael@0 236 {
michael@0 237 NS_ASSERTION(!mRestored, "Already restored!");
michael@0 238 NS_ASSERTION(!mExtraClipUsed, "mExtraClip already used");
michael@0 239 mExtraClipUsed = true;
michael@0 240 mState.ClipContainingBlockDescendants(aRect, aRadii, mExtraClip);
michael@0 241 }
michael@0 242
michael@0 243 protected:
michael@0 244 DisplayItemClip mExtraClip;
michael@0 245 DebugOnly<bool> mExtraClipUsed;
michael@0 246 };
michael@0 247
michael@0 248 }
michael@0 249
michael@0 250 #endif /* DISPLAYLISTCLIPSTATE_H_ */

mercurial