LCOV - code coverage report
Current view: top level - layout/painting - DisplayItemClip.h (source / functions) Hit Total Coverage
Test: output.info Lines: 26 27 96.3 %
Date: 2017-07-14 16:53:18 Functions: 16 17 94.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13