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

mercurial