Bug 1858509 add thread-safety annotations around MediaSourceDemuxer::mMonitor r=alwu
[gecko.git] / layout / painting / DisplayItemClip.h
blobff9df266035df22f3962f4b3c7135201c9333091
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef DISPLAYITEMCLIP_H_
8 #define DISPLAYITEMCLIP_H_
10 #include "mozilla/RefPtr.h"
11 #include "nsRect.h"
12 #include "nsTArray.h"
14 class gfxContext;
15 class nsPresContext;
16 class nsRegion;
18 namespace mozilla {
19 namespace gfx {
20 class DrawTarget;
21 class Path;
22 } // namespace gfx
23 namespace layers {
24 class StackingContextHelper;
25 } // namespace layers
26 namespace wr {
27 struct ComplexClipRegion;
28 } // namespace wr
29 } // namespace mozilla
31 namespace mozilla {
33 /**
34 * An DisplayItemClip represents the intersection of an optional rectangle
35 * with a list of rounded rectangles (which is often empty), all in appunits.
36 * It can represent everything CSS clipping can do to an element (except for
37 * SVG clip-path), including no clipping at all.
39 class DisplayItemClip {
40 typedef mozilla::gfx::DeviceColor DeviceColor;
41 typedef mozilla::gfx::DrawTarget DrawTarget;
42 typedef mozilla::gfx::Path Path;
44 public:
45 struct RoundedRect {
46 nsRect mRect;
47 // Indices into mRadii are the HalfCorner values in gfx/2d/Types.h
48 nscoord mRadii[8];
50 RoundedRect operator+(const nsPoint& aOffset) const {
51 RoundedRect r = *this;
52 r.mRect += aOffset;
53 return r;
55 bool operator==(const RoundedRect& aOther) const {
56 if (!mRect.IsEqualInterior(aOther.mRect)) {
57 return false;
60 for (const auto corner : mozilla::AllPhysicalHalfCorners()) {
61 if (mRadii[corner] != aOther.mRadii[corner]) {
62 return false;
65 return true;
67 bool operator!=(const RoundedRect& aOther) const {
68 return !(*this == aOther);
72 // Constructs a DisplayItemClip that does no clipping at all.
73 DisplayItemClip() : mHaveClipRect(false) {}
75 void SetTo(const nsRect& aRect);
76 void SetTo(const nsRect& aRect, const nscoord* aRadii);
77 void SetTo(const nsRect& aRect, const nsRect& aRoundedRect,
78 const nscoord* aRadii);
79 void IntersectWith(const DisplayItemClip& aOther);
81 // Apply this |DisplayItemClip| to the given gfxContext. Any saving of state
82 // or clearing of other clips must be done by the caller.
83 // See aBegin/aEnd note on ApplyRoundedRectsTo.
84 void ApplyTo(gfxContext* aContext, int32_t A2D) const;
86 void ApplyRectTo(gfxContext* aContext, int32_t A2D) const;
87 // Applies the rounded rects in this Clip to aContext
88 // Will only apply rounded rects from aBegin (inclusive) to aEnd
89 // (exclusive) or the number of rounded rects, whichever is smaller.
90 void ApplyRoundedRectClipsTo(gfxContext* aContext, int32_t A2DPRInt32,
91 uint32_t aBegin, uint32_t aEnd) const;
93 // Draw (fill) the rounded rects in this clip to aContext
94 void FillIntersectionOfRoundedRectClips(gfxContext* aContext,
95 const DeviceColor& aColor,
96 int32_t aAppUnitsPerDevPixel) const;
97 // 'Draw' (create as a path, does not stroke or fill) aRoundRect to aContext
98 already_AddRefed<Path> MakeRoundedRectPath(
99 DrawTarget& aDrawTarget, int32_t A2D,
100 const RoundedRect& aRoundRect) const;
102 // Returns true if the intersection of aRect and this clip region is
103 // non-empty. This is precise for DisplayItemClips with at most one
104 // rounded rectangle. When multiple rounded rectangles are present, we just
105 // check that the rectangle intersects all of them (but possibly in different
106 // places). So it may return true when the correct answer is false.
107 bool MayIntersect(const nsRect& aRect) const;
109 // Return a rectangle contained in the intersection of aRect with this
110 // clip region. Tries to return the largest possible rectangle, but may
111 // not succeed.
112 nsRect ApproximateIntersectInward(const nsRect& aRect) const;
115 * Computes a region which contains the clipped area of this DisplayItemClip,
116 * or if aOldClip is non-null, the union of the clipped area of this
117 * DisplayItemClip with the clipped area of aOldClip translated by aShift.
118 * The result is stored in aCombined. If the result would be infinite
119 * (because one or both of the clips does no clipping), returns false.
121 bool ComputeRegionInClips(const DisplayItemClip* aOldClip,
122 const nsPoint& aShift, nsRegion* aCombined) const;
124 // Returns false if aRect is definitely not clipped by a rounded corner in
125 // this clip. Returns true if aRect is clipped by a rounded corner in this
126 // clip or it can not be quickly determined that it is not clipped by a
127 // rounded corner in this clip.
128 bool IsRectClippedByRoundedCorner(const nsRect& aRect) const;
130 // Returns false if aRect is definitely not clipped by anything in this clip.
131 // Fast but not necessarily accurate.
132 bool IsRectAffectedByClip(const nsRect& aRect) const;
133 bool IsRectAffectedByClip(const nsIntRect& aRect, float aXScale,
134 float aYScale, int32_t A2D) const;
136 // Intersection of all rects in this clip ignoring any rounded corners.
137 nsRect NonRoundedIntersection() const;
139 // Intersect the given rects with all rects in this clip, ignoring any
140 // rounded corners.
141 nsRect ApplyNonRoundedIntersection(const nsRect& aRect) const;
143 // Gets rid of any rounded corners in this clip.
144 void RemoveRoundedCorners();
146 // Adds the difference between Intersect(*this + aPoint, aBounds) and
147 // Intersect(aOther, aOtherBounds) to aDifference (or a bounding-box thereof).
148 void AddOffsetAndComputeDifference(const nsPoint& aPoint,
149 const nsRect& aBounds,
150 const DisplayItemClip& aOther,
151 const nsRect& aOtherBounds,
152 nsRegion* aDifference);
154 bool operator==(const DisplayItemClip& aOther) const {
155 return mHaveClipRect == aOther.mHaveClipRect &&
156 (!mHaveClipRect || mClipRect.IsEqualInterior(aOther.mClipRect)) &&
157 mRoundedClipRects == aOther.mRoundedClipRects;
159 bool operator!=(const DisplayItemClip& aOther) const {
160 return !(*this == aOther);
163 bool HasClip() const { return mHaveClipRect; }
164 const nsRect& GetClipRect() const {
165 NS_ASSERTION(HasClip(), "No clip rect!");
166 return mClipRect;
169 void MoveBy(const nsPoint& aPoint);
171 nsCString ToString() const;
173 uint32_t GetRoundedRectCount() const { return mRoundedClipRects.Length(); }
174 void AppendRoundedRects(nsTArray<RoundedRect>* aArray) const;
176 void ToComplexClipRegions(int32_t aAppUnitsPerDevPixel,
177 nsTArray<wr::ComplexClipRegion>& aOutArray) const;
179 static const DisplayItemClip& NoClip();
181 static void Shutdown();
183 private:
184 nsRect mClipRect;
185 CopyableTArray<RoundedRect> mRoundedClipRects;
186 // If mHaveClipRect is false then this object represents no clipping at all
187 // and mRoundedClipRects must be empty.
188 bool mHaveClipRect;
191 } // namespace mozilla
193 #endif /* DISPLAYITEMCLIP_H_ */