LCOV - code coverage report
Current view: directory - gfx/skia/include/core - SkRegion.h (source / functions) Found Hit Coverage
Test: app.info Lines: 22 0 0.0 %
Date: 2012-06-02 Functions: 14 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2005 The Android Open Source Project
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #ifndef SkRegion_DEFINED
      11                 : #define SkRegion_DEFINED
      12                 : 
      13                 : #include "SkRect.h"
      14                 : 
      15                 : class SkPath;
      16                 : class SkRgnBuilder;
      17                 : 
      18                 : namespace android {
      19                 :     class Region;
      20                 : }
      21                 : 
      22                 : #define SkRegion_gEmptyRunHeadPtr   ((SkRegion::RunHead*)-1)
      23                 : #define SkRegion_gRectRunHeadPtr    0
      24                 : 
      25                 : /** \class SkRegion
      26                 : 
      27                 :     The SkRegion class encapsulates the geometric region used to specify
      28                 :     clipping areas for drawing.
      29                 : */
      30                 : class SK_API SkRegion {
      31                 : public:
      32                 :     typedef int32_t RunType;
      33                 :     enum {
      34                 :         kRunTypeSentinel = 0x7FFFFFFF
      35                 :     };
      36                 :     
      37                 :     SkRegion();
      38                 :     SkRegion(const SkRegion&);
      39                 :     explicit SkRegion(const SkIRect&);
      40                 :     ~SkRegion();
      41                 : 
      42                 :     SkRegion& operator=(const SkRegion&);
      43                 : 
      44                 :     /**
      45                 :      *  Return true if the two regions are equal. i.e. The enclose exactly
      46                 :      *  the same area.
      47                 :      */
      48                 :     friend bool operator==(const SkRegion& a, const SkRegion& b);
      49                 : 
      50                 :     /**
      51                 :      *  Return true if the two regions are not equal.
      52                 :      */
      53                 :     friend bool operator!=(const SkRegion& a, const SkRegion& b) {
      54                 :         return !(a == b);
      55                 :     }
      56                 :     
      57                 :     /**
      58                 :      *  Replace this region with the specified region, and return true if the
      59                 :      *  resulting region is non-empty.
      60                 :      */
      61               0 :     bool set(const SkRegion& src) {
      62               0 :         SkASSERT(&src);
      63               0 :         *this = src;
      64               0 :         return !this->isEmpty();
      65                 :     }
      66                 : 
      67                 :     /**
      68                 :      *  Swap the contents of this and the specified region. This operation
      69                 :      *  is gauarenteed to never fail.
      70                 :      */
      71                 :     void swap(SkRegion&);
      72                 : 
      73                 :     /** Return true if this region is empty */
      74               0 :     bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }
      75                 : 
      76                 :     /** Return true if this region is a single, non-empty rectangle */
      77               0 :     bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }
      78                 : 
      79                 :     /** Return true if this region consists of more than 1 rectangular area */
      80               0 :     bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
      81                 : 
      82                 :     /**
      83                 :      *  Return the bounds of this region. If the region is empty, returns an
      84                 :      *  empty rectangle.
      85                 :      */
      86               0 :     const SkIRect& getBounds() const { return fBounds; }
      87                 : 
      88                 :     /**
      89                 :      *  Returns true if the region is non-empty, and if so, appends the
      90                 :      *  boundary(s) of the region to the specified path.
      91                 :      *  If the region is empty, returns false, and path is left unmodified.
      92                 :      */
      93                 :     bool getBoundaryPath(SkPath* path) const;
      94                 : 
      95                 :     /**
      96                 :      *  Set the region to be empty, and return false, since the resulting
      97                 :      *  region is empty
      98                 :      */
      99                 :     bool setEmpty();
     100                 : 
     101                 :     /**
     102                 :      *  If rect is non-empty, set this region to that rectangle and return true,
     103                 :      *  otherwise set this region to empty and return false.
     104                 :      */
     105                 :     bool setRect(const SkIRect&);
     106                 : 
     107                 :     /**
     108                 :      *  If left < right and top < bottom, set this region to that rectangle and
     109                 :      *  return true, otherwise set this region to empty and return false.
     110                 :      */
     111                 :     bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom);
     112                 : 
     113                 :     /**
     114                 :      *  Set this region to the union of an array of rects. This is generally
     115                 :      *  faster than calling region.op(rect, kUnion_Op) in a loop. If count is
     116                 :      *  0, then this region is set to the empty region.
     117                 :      *  @return true if the resulting region is non-empty
     118                 :      */
     119                 :     bool setRects(const SkIRect rects[], int count);
     120                 :     
     121                 :     /**
     122                 :      *  Set this region to the specified region, and return true if it is
     123                 :      *  non-empty.
     124                 :      */
     125                 :     bool setRegion(const SkRegion&);
     126                 : 
     127                 :     /**
     128                 :      *  Set this region to the area described by the path, clipped.
     129                 :      *  Return true if the resulting region is non-empty.
     130                 :      *  This produces a region that is identical to the pixels that would be
     131                 :      *  drawn by the path (with no antialiasing) with the specified clip.
     132                 :      */
     133                 :     bool setPath(const SkPath&, const SkRegion& clip);
     134                 :     
     135                 :     /**
     136                 :      *  Returns true if the specified rectangle has a non-empty intersection
     137                 :      *  with this region.
     138                 :      */
     139                 :     bool intersects(const SkIRect&) const;
     140                 :     
     141                 :     /**
     142                 :      *  Returns true if the specified region has a non-empty intersection
     143                 :      *  with this region.
     144                 :      */
     145                 :     bool intersects(const SkRegion&) const;
     146                 : 
     147                 :     /**
     148                 :      *  Return true if the specified x,y coordinate is inside the region.
     149                 :      */
     150                 :     bool contains(int32_t x, int32_t y) const;
     151                 : 
     152                 :     /**
     153                 :      *  Return true if the specified rectangle is completely inside the region.
     154                 :      *  This works for simple (rectangular) and complex regions, and always
     155                 :      *  returns the correct result. Note: if either this region or the rectangle
     156                 :      *  is empty, contains() returns false.
     157                 :      */
     158                 :     bool contains(const SkIRect&) const;
     159                 : 
     160                 :     /**
     161                 :      *  Return true if the specified region is completely inside the region.
     162                 :      *  This works for simple (rectangular) and complex regions, and always
     163                 :      *  returns the correct result. Note: if either region is empty, contains()
     164                 :      *  returns false.
     165                 :      */
     166                 :     bool contains(const SkRegion&) const;
     167                 : 
     168                 :     /**
     169                 :      *  Return true if this region is a single rectangle (not complex) and the
     170                 :      *  specified rectangle is contained by this region. Returning false is not
     171                 :      *  a guarantee that the rectangle is not contained by this region, but
     172                 :      *  return true is a guarantee that the rectangle is contained by this region.
     173                 :      */
     174               0 :     bool quickContains(const SkIRect& r) const {
     175               0 :         return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
     176                 :     }
     177                 : 
     178                 :     /**
     179                 :      *  Return true if this region is a single rectangle (not complex) and the
     180                 :      *  specified rectangle is contained by this region. Returning false is not
     181                 :      *  a guarantee that the rectangle is not contained by this region, but
     182                 :      *  return true is a guarantee that the rectangle is contained by this
     183                 :      *  region.
     184                 :      */
     185               0 :     bool quickContains(int32_t left, int32_t top, int32_t right,
     186                 :                        int32_t bottom) const {
     187               0 :         SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
     188                 :         
     189                 :         return left < right && top < bottom &&
     190                 :                fRunHead == SkRegion_gRectRunHeadPtr &&  // this->isRect()
     191                 :                /* fBounds.contains(left, top, right, bottom); */
     192                 :                fBounds.fLeft <= left && fBounds.fTop <= top &&
     193               0 :                fBounds.fRight >= right && fBounds.fBottom >= bottom;
     194                 :     }
     195                 :     
     196                 :     /**
     197                 :      *  Return true if this region is empty, or if the specified rectangle does
     198                 :      *  not intersect the region. Returning false is not a guarantee that they
     199                 :      *  intersect, but returning true is a guarantee that they do not.
     200                 :      */
     201               0 :     bool quickReject(const SkIRect& rect) const {
     202               0 :         return this->isEmpty() || rect.isEmpty() ||
     203               0 :                 !SkIRect::Intersects(fBounds, rect);
     204                 :     }
     205                 : 
     206                 :     /**
     207                 :      *  Return true if this region, or rgn, is empty, or if their bounds do not
     208                 :      *  intersect. Returning false is not a guarantee that they intersect, but
     209                 :      *  returning true is a guarantee that they do not.
     210                 :      */
     211                 :     bool quickReject(const SkRegion& rgn) const {
     212                 :         return this->isEmpty() || rgn.isEmpty() ||
     213                 :                !SkIRect::Intersects(fBounds, rgn.fBounds);
     214                 :     }
     215                 : 
     216                 :     /** Translate the region by the specified (dx, dy) amount. */
     217                 :     void translate(int dx, int dy) { this->translate(dx, dy, this); }
     218                 : 
     219                 :     /**
     220                 :      *  Translate the region by the specified (dx, dy) amount, writing the
     221                 :      *  resulting region into dst. Note: it is legal to pass this region as the
     222                 :      *  dst parameter, effectively translating the region in place. If dst is
     223                 :      *  null, nothing happens.
     224                 :      */
     225                 :     void translate(int dx, int dy, SkRegion* dst) const;
     226                 : 
     227                 :     /**
     228                 :      *  The logical operations that can be performed when combining two regions.
     229                 :      */
     230                 :     enum Op {
     231                 :         kDifference_Op, //!< subtract the op region from the first region
     232                 :         kIntersect_Op,  //!< intersect the two regions
     233                 :         kUnion_Op,      //!< union (inclusive-or) the two regions
     234                 :         kXOR_Op,        //!< exclusive-or the two regions
     235                 :         /** subtract the first region from the op region */
     236                 :         kReverseDifference_Op,
     237                 :         kReplace_Op     //!< replace the dst region with the op region
     238                 :     };
     239                 :     
     240                 :     /**
     241                 :      *  Set this region to the result of applying the Op to this region and the
     242                 :      *  specified rectangle: this = (this op rect).
     243                 :      *  Return true if the resulting region is non-empty.
     244                 :      */
     245               0 :     bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }
     246                 :     
     247                 :     /**
     248                 :      *  Set this region to the result of applying the Op to this region and the
     249                 :      *  specified rectangle: this = (this op rect).
     250                 :      *  Return true if the resulting region is non-empty.
     251                 :      */
     252                 :     bool op(int left, int top, int right, int bottom, Op op) {
     253                 :         SkIRect rect;
     254                 :         rect.set(left, top, right, bottom);
     255                 :         return this->op(*this, rect, op);
     256                 :     }
     257                 :     
     258                 :     /**
     259                 :      *  Set this region to the result of applying the Op to this region and the
     260                 :      *  specified region: this = (this op rgn).
     261                 :      *  Return true if the resulting region is non-empty.
     262                 :      */
     263               0 :     bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
     264                 : 
     265                 :     /**
     266                 :      *  Set this region to the result of applying the Op to the specified
     267                 :      *  rectangle and region: this = (rect op rgn).
     268                 :      *  Return true if the resulting region is non-empty.
     269                 :      */
     270                 :     bool op(const SkIRect& rect, const SkRegion& rgn, Op);
     271                 : 
     272                 :     /**
     273                 :      *  Set this region to the result of applying the Op to the specified
     274                 :      *  region and rectangle: this = (rgn op rect).
     275                 :      *  Return true if the resulting region is non-empty.
     276                 :      */
     277                 :     bool op(const SkRegion& rgn, const SkIRect& rect, Op);
     278                 : 
     279                 :     /**
     280                 :      *  Set this region to the result of applying the Op to the specified
     281                 :      *  regions: this = (rgna op rgnb).
     282                 :      *  Return true if the resulting region is non-empty.
     283                 :      */
     284                 :     bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
     285                 : 
     286                 : #ifdef SK_BUILD_FOR_ANDROID
     287                 :     /** Returns a new char* containing the list of rectangles in this region
     288                 :      */
     289                 :     char* toString();
     290                 : #endif
     291                 : 
     292                 :     /**
     293                 :      *  Returns the sequence of rectangles, sorted in Y and X, that make up
     294                 :      *  this region.
     295                 :      */
     296                 :     class SK_API Iterator {
     297                 :     public:
     298                 :         Iterator() : fRgn(NULL), fDone(true) {}
     299                 :         Iterator(const SkRegion&);
     300                 :         // if we have a region, reset to it and return true, else return false
     301                 :         bool rewind();
     302                 :         // reset the iterator, using the new region
     303                 :         void reset(const SkRegion&);
     304               0 :         bool done() const { return fDone; }
     305                 :         void next();
     306               0 :         const SkIRect& rect() const { return fRect; }
     307                 :         // may return null
     308                 :         const SkRegion* rgn() const { return fRgn; }
     309                 : 
     310                 :     private:
     311                 :         const SkRegion* fRgn;
     312                 :         const RunType*  fRuns;
     313                 :         SkIRect         fRect;
     314                 :         bool            fDone;
     315                 :     };
     316                 : 
     317                 :     /**
     318                 :      *  Returns the sequence of rectangles, sorted in Y and X, that make up
     319                 :      *  this region intersected with the specified clip rectangle.
     320                 :      */
     321                 :     class SK_API Cliperator {
     322                 :     public:
     323                 :         Cliperator(const SkRegion&, const SkIRect& clip);
     324               0 :         bool done() { return fDone; }
     325                 :         void  next();
     326               0 :         const SkIRect& rect() const { return fRect; }
     327                 : 
     328                 :     private:
     329                 :         Iterator    fIter;
     330                 :         SkIRect     fClip;
     331                 :         SkIRect     fRect;
     332                 :         bool        fDone;
     333                 :     };
     334                 : 
     335                 :     /**
     336                 :      *  Returns the sequence of runs that make up this region for the specified
     337                 :      *  Y scanline, clipped to the specified left and right X values.
     338                 :      */
     339                 :     class Spanerator {
     340                 :     public:
     341                 :         Spanerator(const SkRegion&, int y, int left, int right);
     342                 :         bool next(int* left, int* right);
     343                 : 
     344                 :     private:
     345                 :         const SkRegion::RunType* fRuns;
     346                 :         int     fLeft, fRight;
     347                 :         bool    fDone;
     348                 :     };
     349                 : 
     350                 :     /**
     351                 :      *  Write the region to the buffer, and return the number of bytes written.
     352                 :      *  If buffer is NULL, it still returns the number of bytes.
     353                 :      */
     354                 :     uint32_t flatten(void* buffer) const;
     355                 : 
     356                 :     /**
     357                 :      *  Initialized the region from the buffer, returning the number
     358                 :      *  of bytes actually read.
     359                 :      */
     360                 :     uint32_t unflatten(const void* buffer);
     361                 : 
     362                 :     /**
     363                 :      *  Returns a reference to a global empty region. Just a convenience for
     364                 :      *  callers that need a const empty region.
     365                 :      */
     366                 :     static const SkRegion& GetEmptyRegion();
     367                 : 
     368                 :     SkDEBUGCODE(void dump() const;)
     369                 :     SkDEBUGCODE(void validate() const;)
     370                 :     SkDEBUGCODE(static void UnitTest();)
     371                 : 
     372                 :     // expose this to allow for regression test on complex regions
     373                 :     SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
     374                 : 
     375                 : private:
     376                 :     enum {
     377                 :         kOpCount = kReplace_Op + 1
     378                 :     };
     379                 : 
     380                 :     enum {
     381                 :         kRectRegionRuns = 6 // need to store a region of a rect [T B L R S S]        
     382                 :     };
     383                 : 
     384                 :     friend class android::Region;    // needed for marshalling efficiently
     385                 :     void allocateRuns(int count); // allocate space for count runs
     386                 : 
     387                 :     struct RunHead;
     388                 : 
     389                 :     SkIRect     fBounds;
     390                 :     RunHead*    fRunHead;
     391                 : 
     392                 :     void            freeRuns();
     393                 :     const RunType*  getRuns(RunType tmpStorage[], int* count) const;
     394                 :     bool            setRuns(RunType runs[], int count);
     395                 : 
     396                 :     int count_runtype_values(int* itop, int* ibot) const;
     397                 :     
     398                 :     static void BuildRectRuns(const SkIRect& bounds,
     399                 :                               RunType runs[kRectRegionRuns]);
     400                 :     // returns true if runs are just a rect
     401                 :     static bool ComputeRunBounds(const RunType runs[], int count,
     402                 :                                  SkIRect* bounds);
     403                 : 
     404                 :     friend struct RunHead;
     405                 :     friend class Iterator;
     406                 :     friend class Spanerator;
     407                 :     friend class SkRgnBuilder;
     408                 :     friend class SkFlatRegion;
     409                 : };
     410                 : 
     411                 : #endif

Generated by: LCOV version 1.7