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 DISPLAYITEMCLIP_H_
7 #define DISPLAYITEMCLIP_H_
11 #include "nsStyleConsts.h"
21 * An DisplayItemClip represents the intersection of an optional rectangle
22 * with a list of rounded rectangles (which is often empty), all in appunits.
23 * It can represent everything CSS clipping can do to an element (except for
24 * SVG clip-path), including no clipping at all.
26 class DisplayItemClip
{
30 // Indices into mRadii are the NS_CORNER_* constants in nsStyleConsts.h
33 RoundedRect
operator+(const nsPoint
& aOffset
) const {
34 RoundedRect r
= *this;
38 bool operator==(const RoundedRect
& aOther
) const {
39 if (!mRect
.IsEqualInterior(aOther
.mRect
)) {
43 NS_FOR_CSS_HALF_CORNERS(corner
) {
44 if (mRadii
[corner
] != aOther
.mRadii
[corner
]) {
50 bool operator!=(const RoundedRect
& aOther
) const {
51 return !(*this == aOther
);
55 // Constructs a DisplayItemClip that does no clipping at all.
56 DisplayItemClip() : mHaveClipRect(false) {}
58 void SetTo(const nsRect
& aRect
);
59 void SetTo(const nsRect
& aRect
, const nscoord
* aRadii
);
60 void SetTo(const nsRect
& aRect
, const nsRect
& aRoundedRect
, const nscoord
* aRadii
);
61 void IntersectWith(const DisplayItemClip
& aOther
);
63 // Apply this |DisplayItemClip| to the given gfxContext. Any saving of state
64 // or clearing of other clips must be done by the caller.
65 // See aBegin/aEnd note on ApplyRoundedRectsTo.
66 void ApplyTo(gfxContext
* aContext
, nsPresContext
* aPresContext
,
67 uint32_t aBegin
= 0, uint32_t aEnd
= UINT32_MAX
);
69 void ApplyRectTo(gfxContext
* aContext
, int32_t A2D
) const;
70 // Applies the rounded rects in this Clip to aContext
71 // Will only apply rounded rects from aBegin (inclusive) to aEnd
72 // (exclusive) or the number of rounded rects, whichever is smaller.
73 void ApplyRoundedRectsTo(gfxContext
* aContext
, int32_t A2DPRInt32
,
74 uint32_t aBegin
, uint32_t aEnd
) const;
76 // Draw (fill) the rounded rects in this clip to aContext
77 void DrawRoundedRectsTo(gfxContext
* aContext
, int32_t A2D
,
78 uint32_t aBegin
, uint32_t aEnd
) const;
79 // 'Draw' (create as a path, does not stroke or fill) aRoundRect to aContext
80 void AddRoundedRectPathTo(gfxContext
* aContext
, int32_t A2D
,
81 const RoundedRect
&aRoundRect
) const;
83 // Returns true if the intersection of aRect and this clip region is
84 // non-empty. This is precise for DisplayItemClips with at most one
85 // rounded rectangle. When multiple rounded rectangles are present, we just
86 // check that the rectangle intersects all of them (but possibly in different
87 // places). So it may return true when the correct answer is false.
88 bool MayIntersect(const nsRect
& aRect
) const;
90 // Return a rectangle contained in the intersection of aRect with this
91 // clip region. Tries to return the largest possible rectangle, but may
93 nsRect
ApproximateIntersectInward(const nsRect
& aRect
) const;
96 * Computes a region which contains the clipped area of this DisplayItemClip,
97 * or if aOldClip is non-null, the union of the clipped area of this
98 * DisplayItemClip with the clipped area of aOldClip translated by aShift.
99 * The result is stored in aCombined. If the result would be infinite
100 * (because one or both of the clips does no clipping), returns false.
102 bool ComputeRegionInClips(DisplayItemClip
* aOldClip
,
103 const nsPoint
& aShift
,
104 nsRegion
* aCombined
) const;
106 // Returns false if aRect is definitely not clipped by a rounded corner in
107 // this clip. Returns true if aRect is clipped by a rounded corner in this
108 // clip or it can not be quickly determined that it is not clipped by a
109 // rounded corner in this clip.
110 bool IsRectClippedByRoundedCorner(const nsRect
& aRect
) const;
112 // Returns false if aRect is definitely not clipped by anything in this clip.
113 // Fast but not necessarily accurate.
114 bool IsRectAffectedByClip(const nsRect
& aRect
) const;
115 bool IsRectAffectedByClip(const nsIntRect
& aRect
, float aXScale
, float aYScale
, int32_t A2D
) const;
117 // Intersection of all rects in this clip ignoring any rounded corners.
118 nsRect
NonRoundedIntersection() const;
120 // Intersect the given rects with all rects in this clip, ignoring any
122 nsRect
ApplyNonRoundedIntersection(const nsRect
& aRect
) const;
124 // Gets rid of any rounded corners in this clip.
125 void RemoveRoundedCorners();
127 // Adds the difference between Intersect(*this + aPoint, aBounds) and
128 // Intersect(aOther, aOtherBounds) to aDifference (or a bounding-box thereof).
129 void AddOffsetAndComputeDifference(uint32_t aStart
, const nsPoint
& aPoint
, const nsRect
& aBounds
,
130 const DisplayItemClip
& aOther
, uint32_t aOtherStart
, const nsRect
& aOtherBounds
,
131 nsRegion
* aDifference
);
133 bool operator==(const DisplayItemClip
& aOther
) const {
134 return mHaveClipRect
== aOther
.mHaveClipRect
&&
135 (!mHaveClipRect
|| mClipRect
.IsEqualInterior(aOther
.mClipRect
)) &&
136 mRoundedClipRects
== aOther
.mRoundedClipRects
;
138 bool operator!=(const DisplayItemClip
& aOther
) const {
139 return !(*this == aOther
);
142 bool HasClip() const { return mHaveClipRect
; }
143 const nsRect
& GetClipRect() const
145 NS_ASSERTION(HasClip(), "No clip rect!");
149 void MoveBy(nsPoint aPoint
);
151 #ifdef MOZ_DUMP_PAINTING
152 nsCString
ToString() const;
156 * Find the largest N such that the first N rounded rects in 'this' are
157 * equal to the first N rounded rects in aOther, and N <= aMax.
159 uint32_t GetCommonRoundedRectCount(const DisplayItemClip
& aOther
,
160 uint32_t aMax
) const;
161 uint32_t GetRoundedRectCount() const { return mRoundedClipRects
.Length(); }
162 void AppendRoundedRects(nsTArray
<RoundedRect
>* aArray
, uint32_t aCount
) const;
164 static const DisplayItemClip
& NoClip();
166 static void Shutdown();
170 nsTArray
<RoundedRect
> mRoundedClipRects
;
171 // If mHaveClipRect is false then this object represents no clipping at all
172 // and mRoundedClipRects must be empty.
178 #endif /* DISPLAYITEMCLIP_H_ */