Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2010 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkRasterClip_DEFINED
      9 #define SkRasterClip_DEFINED
     10 
     11 #include "SkRegion.h"
     12 #include "SkAAClip.h"
     13 
     14 class SkRasterClip {
     15 public:
     16     SkRasterClip();
     17     SkRasterClip(const SkIRect&);
     18     SkRasterClip(const SkRasterClip&);
     19     ~SkRasterClip();
     20 
     21     bool isBW() const { return fIsBW; }
     22     bool isAA() const { return !fIsBW; }
     23     const SkRegion& bwRgn() const { SkASSERT(fIsBW); return fBW; }
     24     const SkAAClip& aaRgn() const { SkASSERT(!fIsBW); return fAA; }
     25 
     26     bool isEmpty() const {
     27         SkASSERT(this->computeIsEmpty() == fIsEmpty);
     28         return fIsEmpty;
     29     }
     30 
     31     bool isRect() const {
     32         SkASSERT(this->computeIsRect() == fIsRect);
     33         return fIsRect;
     34     }
     35 
     36     bool isComplex() const;
     37     const SkIRect& getBounds() const;
     38 
     39     bool setEmpty();
     40     bool setRect(const SkIRect&);
     41 
     42     bool setPath(const SkPath& path, const SkRegion& clip, bool doAA);
     43     bool setPath(const SkPath& path, const SkIRect& clip, bool doAA);
     44     bool setPath(const SkPath& path, const SkRasterClip&, bool doAA);
     45 
     46     bool op(const SkIRect&, SkRegion::Op);
     47     bool op(const SkRegion&, SkRegion::Op);
     48     bool op(const SkRasterClip&, SkRegion::Op);
     49     bool op(const SkRect&, SkRegion::Op, bool doAA);
     50 
     51     void translate(int dx, int dy, SkRasterClip* dst) const;
     52     void translate(int dx, int dy) {
     53         this->translate(dx, dy, this);
     54     }
     55 
     56     bool quickContains(const SkIRect& rect) const;
     57     bool quickContains(int left, int top, int right, int bottom) const {
     58         return quickContains(SkIRect::MakeLTRB(left, top, right, bottom));
     59     }
     60 
     61     /**
     62      *  Return true if this region is empty, or if the specified rectangle does
     63      *  not intersect the region. Returning false is not a guarantee that they
     64      *  intersect, but returning true is a guarantee that they do not.
     65      */
     66     bool quickReject(const SkIRect& rect) const {
     67         return this->isEmpty() || rect.isEmpty() ||
     68                !SkIRect::Intersects(this->getBounds(), rect);
     69     }
     70 
     71     // hack for SkCanvas::getTotalClip
     72     const SkRegion& forceGetBW();
     73 
     74 #ifdef SK_DEBUG
     75     void validate() const;
     76 #else
     77     void validate() const {}
     78 #endif
     79 
     80 private:
     81     SkRegion    fBW;
     82     SkAAClip    fAA;
     83     bool        fIsBW;
     84     // these 2 are caches based on querying the right obj based on fIsBW
     85     bool        fIsEmpty;
     86     bool        fIsRect;
     87 
     88     bool computeIsEmpty() const {
     89         return fIsBW ? fBW.isEmpty() : fAA.isEmpty();
     90     }
     91 
     92     bool computeIsRect() const {
     93         return fIsBW ? fBW.isRect() : false;
     94     }
     95 
     96     bool updateCacheAndReturnNonEmpty() {
     97         fIsEmpty = this->computeIsEmpty();
     98         fIsRect = this->computeIsRect();
     99         return !fIsEmpty;
    100     }
    101 
    102     void convertToAA();
    103 };
    104 
    105 class SkAutoRasterClipValidate : SkNoncopyable {
    106 public:
    107     SkAutoRasterClipValidate(const SkRasterClip& rc) : fRC(rc) {
    108         fRC.validate();
    109     }
    110     ~SkAutoRasterClipValidate() {
    111         fRC.validate();
    112     }
    113 private:
    114     const SkRasterClip& fRC;
    115 };
    116 
    117 #ifdef SK_DEBUG
    118     #define AUTO_RASTERCLIP_VALIDATE(rc)    SkAutoRasterClipValidate arcv(rc)
    119 #else
    120     #define AUTO_RASTERCLIP_VALIDATE(rc)
    121 #endif
    122 
    123 ///////////////////////////////////////////////////////////////////////////////
    124 
    125 /**
    126  *  Encapsulates the logic of deciding if we need to change/wrap the blitter
    127  *  for aaclipping. If so, getRgn and getBlitter return modified values. If
    128  *  not, they return the raw blitter and (bw) clip region.
    129  *
    130  *  We need to keep the constructor/destructor cost as small as possible, so we
    131  *  can freely put this guy on the stack, and not pay too much for the case when
    132  *  we're really BW anyways.
    133  */
    134 class SkAAClipBlitterWrapper {
    135 public:
    136     SkAAClipBlitterWrapper();
    137     SkAAClipBlitterWrapper(const SkRasterClip&, SkBlitter*);
    138     SkAAClipBlitterWrapper(const SkAAClip*, SkBlitter*);
    139 
    140     void init(const SkRasterClip&, SkBlitter*);
    141 
    142     const SkIRect& getBounds() const {
    143         SkASSERT(fClipRgn);
    144         return fClipRgn->getBounds();
    145     }
    146     const SkRegion& getRgn() const {
    147         SkASSERT(fClipRgn);
    148         return *fClipRgn;
    149     }
    150     SkBlitter* getBlitter() {
    151         SkASSERT(fBlitter);
    152         return fBlitter;
    153     }
    154 
    155 private:
    156     const SkAAClip* fAAClip;
    157     SkRegion        fBWRgn;
    158     SkAAClipBlitter fAABlitter;
    159     // what we return
    160     const SkRegion* fClipRgn;
    161     SkBlitter* fBlitter;
    162 };
    163 
    164 #endif
    165