summaryrefslogtreecommitdiffstats
path: root/layout/base/DisplayItemScrollClip.h
diff options
context:
space:
mode:
Diffstat (limited to 'layout/base/DisplayItemScrollClip.h')
-rw-r--r--layout/base/DisplayItemScrollClip.h126
1 files changed, 126 insertions, 0 deletions
diff --git a/layout/base/DisplayItemScrollClip.h b/layout/base/DisplayItemScrollClip.h
new file mode 100644
index 000000000..ee3335972
--- /dev/null
+++ b/layout/base/DisplayItemScrollClip.h
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DISPLAYITEMSCROLLCLIP_H_
+#define DISPLAYITEMSCROLLCLIP_H_
+
+#include "mozilla/Assertions.h"
+#include "nsString.h"
+
+class nsIScrollableFrame;
+
+namespace mozilla {
+
+class DisplayItemClip;
+
+/**
+ * A DisplayItemScrollClip represents a DisplayItemClip from a scrollable
+ * frame. This clip is stored on a display item separately from the item's
+ * regular DisplayItemClip for async scrolling purposes: The item's regular
+ * clip can be fused to the item's contents when drawing layer contents, but
+ * scroll clips need to be kept separate so that they can be applied at
+ * composition time, after any async scroll offsets have been applied.
+ * Scroll clips are created during display list construction when
+ * async-scrollable scroll frames are entered. At that point, the current
+ * regular clip is cleared on the display list clip state. They are also
+ * created for scroll frames that are inactivate and not async scrollable;
+ * in that case, mIsAsyncScrollable on the scroll clip will be false.
+ * When async-scrollable scroll frames are nested, the inner display items
+ * can walk the whole chain of scroll clips via the DisplayItemScrollClip's
+ * mParent pointer.
+ * Storing scroll clips on display items allows easy access of all scroll
+ * frames that affect a certain display item, and it allows some display list
+ * operations to compute more accurate clips, for example when computing the
+ * bounds of a container item for a frame that contains an async-scrollable
+ * scroll frame.
+ */
+class DisplayItemScrollClip {
+public:
+ DisplayItemScrollClip(const DisplayItemScrollClip* aParent,
+ nsIScrollableFrame* aScrollableFrame,
+ const DisplayItemClip* aClip,
+ bool aIsAsyncScrollable)
+ : mParent(aParent)
+ , mScrollableFrame(aScrollableFrame)
+ , mClip(aClip)
+ , mIsAsyncScrollable(aIsAsyncScrollable)
+ , mDepth(aParent ? aParent->mDepth + 1 : 1)
+ {
+ MOZ_ASSERT(mScrollableFrame);
+ }
+
+ /**
+ * "Pick descendant" is analogous to the intersection operation on regular
+ * clips: In some cases, there are multiple candidate clips that can apply to
+ * an item, one of them being the ancestor of the other. This method picks
+ * the descendant.
+ * Both aClip1 and aClip2 are allowed to be null.
+ */
+ static const DisplayItemScrollClip*
+ PickDescendant(const DisplayItemScrollClip* aClip1,
+ const DisplayItemScrollClip* aClip2)
+ {
+ MOZ_ASSERT(IsAncestor(aClip1, aClip2) || IsAncestor(aClip2, aClip1),
+ "one of the scroll clips must be an ancestor of the other");
+ return Depth(aClip1) > Depth(aClip2) ? aClip1 : aClip2;
+ }
+
+ static const DisplayItemScrollClip*
+ PickAncestor(const DisplayItemScrollClip* aClip1,
+ const DisplayItemScrollClip* aClip2)
+ {
+ MOZ_ASSERT(IsAncestor(aClip1, aClip2) || IsAncestor(aClip2, aClip1),
+ "one of the scroll clips must be an ancestor of the other");
+ return Depth(aClip1) < Depth(aClip2) ? aClip1 : aClip2;
+ }
+
+
+ /**
+ * Returns whether aAncestor is an ancestor scroll clip of aDescendant.
+ * A scroll clip that's null is considered the root scroll clip.
+ */
+ static bool IsAncestor(const DisplayItemScrollClip* aAncestor,
+ const DisplayItemScrollClip* aDescendant);
+
+ /**
+ * Return a string which contains the list of stringified clips for this
+ * scroll clip and its ancestors. aScrollClip can be null.
+ */
+ static nsCString ToString(const DisplayItemScrollClip* aScrollClip);
+
+ bool HasRoundedCorners() const;
+
+ /**
+ * The previous (outer) scroll clip, or null.
+ */
+ const DisplayItemScrollClip* mParent;
+
+ /**
+ * The scrollable frame that this scroll clip is for. Always non-null.
+ */
+ nsIScrollableFrame* mScrollableFrame;
+
+ /**
+ * The clip represented by this scroll clip, relative to mScrollableFrame's
+ * reference frame. Can be null.
+ */
+ const DisplayItemClip* mClip;
+
+ /**
+ * Whether this scroll clip is for an async-scrollable scroll frame.
+ * Can change during display list construction.
+ */
+ bool mIsAsyncScrollable;
+
+private:
+ static uint32_t Depth(const DisplayItemScrollClip* aSC)
+ { return aSC ? aSC->mDepth : 0; }
+
+ const uint32_t mDepth;
+};
+
+} // namespace mozilla
+
+#endif /* DISPLAYITEMSCROLLCLIP_H_ */