tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DisplayItemClip.h (7188B)


      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/. */
      6 
      7 #ifndef DISPLAYITEMCLIP_H_
      8 #define DISPLAYITEMCLIP_H_
      9 
     10 #include "mozilla/AlreadyAddRefed.h"
     11 #include "nsRect.h"
     12 #include "nsTArray.h"
     13 
     14 class gfxContext;
     15 class nsPresContext;
     16 class nsRegion;
     17 
     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
     30 
     31 namespace mozilla {
     32 
     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.
     38 */
     39 class DisplayItemClip {
     40  typedef mozilla::gfx::DeviceColor DeviceColor;
     41  typedef mozilla::gfx::DrawTarget DrawTarget;
     42  typedef mozilla::gfx::Path Path;
     43 
     44 public:
     45  struct RoundedRect {
     46    nsRect mRect;
     47    // Indices into mRadii are the HalfCorner values in gfx/2d/Types.h
     48    nsRectCornerRadii mRadii;
     49 
     50    RoundedRect operator+(const nsPoint& aOffset) const {
     51      RoundedRect r = *this;
     52      r.mRect += aOffset;
     53      return r;
     54    }
     55    bool operator==(const RoundedRect& aOther) const {
     56      if (!mRect.IsEqualInterior(aOther.mRect)) {
     57        return false;
     58      }
     59      if (mRadii != aOther.mRadii) {
     60        return false;
     61      }
     62      return true;
     63    }
     64    bool operator!=(const RoundedRect& aOther) const {
     65      return !(*this == aOther);
     66    }
     67  };
     68 
     69  // Constructs a DisplayItemClip that does no clipping at all.
     70  DisplayItemClip() : mHaveClipRect(false) {}
     71 
     72  void SetTo(const nsRect& aRect);
     73  void SetTo(const nsRect& aRect, const nsRectCornerRadii* aRadii);
     74  void SetTo(const nsRect& aRect, const nsRect& aRoundedRect,
     75             const nsRectCornerRadii* aRadii);
     76  void IntersectWith(const DisplayItemClip& aOther);
     77 
     78  // Apply this |DisplayItemClip| to the given gfxContext.  Any saving of state
     79  // or clearing of other clips must be done by the caller.
     80  // See aBegin/aEnd note on ApplyRoundedRectsTo.
     81  void ApplyTo(gfxContext* aContext, int32_t A2D) const;
     82 
     83  void ApplyRectTo(gfxContext* aContext, int32_t A2D) const;
     84  // Applies the rounded rects in this Clip to aContext
     85  // Will only apply rounded rects from aBegin (inclusive) to aEnd
     86  // (exclusive) or the number of rounded rects, whichever is smaller.
     87  void ApplyRoundedRectClipsTo(gfxContext* aContext, int32_t A2DPRInt32,
     88                               uint32_t aBegin, uint32_t aEnd) const;
     89 
     90  // Draw (fill) the rounded rects in this clip to aContext
     91  void FillIntersectionOfRoundedRectClips(gfxContext* aContext,
     92                                          const DeviceColor& aColor,
     93                                          int32_t aAppUnitsPerDevPixel) const;
     94  // 'Draw' (create as a path, does not stroke or fill) aRoundRect to aContext
     95  already_AddRefed<Path> MakeRoundedRectPath(
     96      DrawTarget& aDrawTarget, int32_t A2D,
     97      const RoundedRect& aRoundRect) const;
     98 
     99  // Returns true if the intersection of aRect and this clip region is
    100  // non-empty. This is precise for DisplayItemClips with at most one
    101  // rounded rectangle. When multiple rounded rectangles are present, we just
    102  // check that the rectangle intersects all of them (but possibly in different
    103  // places). So it may return true when the correct answer is false.
    104  bool MayIntersect(const nsRect& aRect) const;
    105 
    106  // Return a rectangle contained in the intersection of aRect with this
    107  // clip region. Tries to return the largest possible rectangle, but may
    108  // not succeed.
    109  nsRect ApproximateIntersectInward(const nsRect& aRect) const;
    110 
    111  /*
    112   * Computes a region which contains the clipped area of this DisplayItemClip,
    113   * or if aOldClip is non-null, the union of the clipped area of this
    114   * DisplayItemClip with the clipped area of aOldClip translated by aShift.
    115   * The result is stored in aCombined. If the result would be infinite
    116   * (because one or both of the clips does no clipping), returns false.
    117   */
    118  bool ComputeRegionInClips(const DisplayItemClip* aOldClip,
    119                            const nsPoint& aShift, nsRegion* aCombined) const;
    120 
    121  // Returns false if aRect is definitely not clipped by a rounded corner in
    122  // this clip. Returns true if aRect is clipped by a rounded corner in this
    123  // clip or it can not be quickly determined that it is not clipped by a
    124  // rounded corner in this clip.
    125  bool IsRectClippedByRoundedCorner(const nsRect& aRect) const;
    126 
    127  // Returns false if aRect is definitely not clipped by anything in this clip.
    128  // Fast but not necessarily accurate.
    129  bool IsRectAffectedByClip(const nsRect& aRect) const;
    130  bool IsRectAffectedByClip(const nsIntRect& aRect, float aXScale,
    131                            float aYScale, int32_t A2D) const;
    132 
    133  // Intersection of all rects in this clip ignoring any rounded corners.
    134  nsRect NonRoundedIntersection() const;
    135 
    136  // Intersect the given rects with all rects in this clip, ignoring any
    137  // rounded corners.
    138  nsRect ApplyNonRoundedIntersection(const nsRect& aRect) const;
    139 
    140  // Gets rid of any rounded corners in this clip.
    141  void RemoveRoundedCorners();
    142 
    143  // Adds the difference between Intersect(*this + aPoint, aBounds) and
    144  // Intersect(aOther, aOtherBounds) to aDifference (or a bounding-box thereof).
    145  void AddOffsetAndComputeDifference(const nsPoint& aPoint,
    146                                     const nsRect& aBounds,
    147                                     const DisplayItemClip& aOther,
    148                                     const nsRect& aOtherBounds,
    149                                     nsRegion* aDifference);
    150 
    151  bool operator==(const DisplayItemClip& aOther) const {
    152    return mHaveClipRect == aOther.mHaveClipRect &&
    153           (!mHaveClipRect || mClipRect.IsEqualInterior(aOther.mClipRect)) &&
    154           mRoundedClipRects == aOther.mRoundedClipRects;
    155  }
    156  bool operator!=(const DisplayItemClip& aOther) const {
    157    return !(*this == aOther);
    158  }
    159 
    160  bool HasClip() const { return mHaveClipRect; }
    161  const nsRect& GetClipRect() const {
    162    NS_ASSERTION(HasClip(), "No clip rect!");
    163    return mClipRect;
    164  }
    165 
    166  void MoveBy(const nsPoint& aPoint);
    167 
    168  nsCString ToString() const;
    169 
    170  uint32_t GetRoundedRectCount() const { return mRoundedClipRects.Length(); }
    171  void AppendRoundedRects(nsTArray<RoundedRect>* aArray) const;
    172 
    173  void ToComplexClipRegions(int32_t aAppUnitsPerDevPixel,
    174                            nsTArray<wr::ComplexClipRegion>& aOutArray) const;
    175 
    176  static const DisplayItemClip& NoClip();
    177 
    178  static void Shutdown();
    179 
    180 private:
    181  nsRect mClipRect;
    182  CopyableTArray<RoundedRect> mRoundedClipRects;
    183  // If mHaveClipRect is false then this object represents no clipping at all
    184  // and mRoundedClipRects must be empty.
    185  bool mHaveClipRect;
    186 };
    187 
    188 }  // namespace mozilla
    189 
    190 #endif /* DISPLAYITEMCLIP_H_ */