gfx/skia/trunk/include/core/SkRegion.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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  */
    10 #ifndef SkRegion_DEFINED
    11 #define SkRegion_DEFINED
    13 #include "SkRect.h"
    15 class SkPath;
    16 class SkRgnBuilder;
    18 namespace android {
    19     class Region;
    20 }
    22 #define SkRegion_gEmptyRunHeadPtr   ((SkRegion::RunHead*)-1)
    23 #define SkRegion_gRectRunHeadPtr    0
    25 /** \class SkRegion
    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     };
    37     SkRegion();
    38     SkRegion(const SkRegion&);
    39     explicit SkRegion(const SkIRect&);
    40     ~SkRegion();
    42     SkRegion& operator=(const SkRegion&);
    44     /**
    45      *  Return true if the two regions are equal. i.e. The enclose exactly
    46      *  the same area.
    47      */
    48     bool operator==(const SkRegion& other) const;
    50     /**
    51      *  Return true if the two regions are not equal.
    52      */
    53     bool operator!=(const SkRegion& other) const {
    54         return !(*this == other);
    55     }
    57     /**
    58      *  Replace this region with the specified region, and return true if the
    59      *  resulting region is non-empty.
    60      */
    61     bool set(const SkRegion& src) {
    62         SkASSERT(&src);
    63         *this = src;
    64         return !this->isEmpty();
    65     }
    67     /**
    68      *  Swap the contents of this and the specified region. This operation
    69      *  is gauarenteed to never fail.
    70      */
    71     void swap(SkRegion&);
    73     /** Return true if this region is empty */
    74     bool isEmpty() const { return fRunHead == SkRegion_gEmptyRunHeadPtr; }
    76     /** Return true if this region is a single, non-empty rectangle */
    77     bool isRect() const { return fRunHead == SkRegion_gRectRunHeadPtr; }
    79     /** Return true if this region consists of more than 1 rectangular area */
    80     bool isComplex() const { return !this->isEmpty() && !this->isRect(); }
    82     /**
    83      *  Return the bounds of this region. If the region is empty, returns an
    84      *  empty rectangle.
    85      */
    86     const SkIRect& getBounds() const { return fBounds; }
    88     /**
    89      *  Returns a value that grows approximately linearly with the number of
    90      *  intervals comprised in the region. Empty region will return 0, Rect
    91      *  will return 1, Complex will return a value > 1.
    92      *
    93      *  Use this to compare two regions, where the larger count likely
    94      *  indicates a more complex region.
    95      */
    96     int computeRegionComplexity() const;
    98     /**
    99      *  Returns true if the region is non-empty, and if so, appends the
   100      *  boundary(s) of the region to the specified path.
   101      *  If the region is empty, returns false, and path is left unmodified.
   102      */
   103     bool getBoundaryPath(SkPath* path) const;
   105     /**
   106      *  Set the region to be empty, and return false, since the resulting
   107      *  region is empty
   108      */
   109     bool setEmpty();
   111     /**
   112      *  If rect is non-empty, set this region to that rectangle and return true,
   113      *  otherwise set this region to empty and return false.
   114      */
   115     bool setRect(const SkIRect&);
   117     /**
   118      *  If left < right and top < bottom, set this region to that rectangle and
   119      *  return true, otherwise set this region to empty and return false.
   120      */
   121     bool setRect(int32_t left, int32_t top, int32_t right, int32_t bottom);
   123     /**
   124      *  Set this region to the union of an array of rects. This is generally
   125      *  faster than calling region.op(rect, kUnion_Op) in a loop. If count is
   126      *  0, then this region is set to the empty region.
   127      *  @return true if the resulting region is non-empty
   128      */
   129     bool setRects(const SkIRect rects[], int count);
   131     /**
   132      *  Set this region to the specified region, and return true if it is
   133      *  non-empty.
   134      */
   135     bool setRegion(const SkRegion&);
   137     /**
   138      *  Set this region to the area described by the path, clipped.
   139      *  Return true if the resulting region is non-empty.
   140      *  This produces a region that is identical to the pixels that would be
   141      *  drawn by the path (with no antialiasing) with the specified clip.
   142      */
   143     bool setPath(const SkPath&, const SkRegion& clip);
   145     /**
   146      *  Returns true if the specified rectangle has a non-empty intersection
   147      *  with this region.
   148      */
   149     bool intersects(const SkIRect&) const;
   151     /**
   152      *  Returns true if the specified region has a non-empty intersection
   153      *  with this region.
   154      */
   155     bool intersects(const SkRegion&) const;
   157     /**
   158      *  Return true if the specified x,y coordinate is inside the region.
   159      */
   160     bool contains(int32_t x, int32_t y) const;
   162     /**
   163      *  Return true if the specified rectangle is completely inside the region.
   164      *  This works for simple (rectangular) and complex regions, and always
   165      *  returns the correct result. Note: if either this region or the rectangle
   166      *  is empty, contains() returns false.
   167      */
   168     bool contains(const SkIRect&) const;
   170     /**
   171      *  Return true if the specified region is completely inside the region.
   172      *  This works for simple (rectangular) and complex regions, and always
   173      *  returns the correct result. Note: if either region is empty, contains()
   174      *  returns false.
   175      */
   176     bool contains(const SkRegion&) const;
   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 region.
   183      */
   184     bool quickContains(const SkIRect& r) const {
   185         return this->quickContains(r.fLeft, r.fTop, r.fRight, r.fBottom);
   186     }
   188     /**
   189      *  Return true if this region is a single rectangle (not complex) and the
   190      *  specified rectangle is contained by this region. Returning false is not
   191      *  a guarantee that the rectangle is not contained by this region, but
   192      *  return true is a guarantee that the rectangle is contained by this
   193      *  region.
   194      */
   195     bool quickContains(int32_t left, int32_t top, int32_t right,
   196                        int32_t bottom) const {
   197         SkASSERT(this->isEmpty() == fBounds.isEmpty()); // valid region
   199         return left < right && top < bottom &&
   200                fRunHead == SkRegion_gRectRunHeadPtr &&  // this->isRect()
   201                /* fBounds.contains(left, top, right, bottom); */
   202                fBounds.fLeft <= left && fBounds.fTop <= top &&
   203                fBounds.fRight >= right && fBounds.fBottom >= bottom;
   204     }
   206     /**
   207      *  Return true if this region is empty, or if the specified rectangle does
   208      *  not intersect the region. Returning false is not a guarantee that they
   209      *  intersect, but returning true is a guarantee that they do not.
   210      */
   211     bool quickReject(const SkIRect& rect) const {
   212         return this->isEmpty() || rect.isEmpty() ||
   213                 !SkIRect::Intersects(fBounds, rect);
   214     }
   216     /**
   217      *  Return true if this region, or rgn, is empty, or if their bounds do not
   218      *  intersect. Returning false is not a guarantee that they intersect, but
   219      *  returning true is a guarantee that they do not.
   220      */
   221     bool quickReject(const SkRegion& rgn) const {
   222         return this->isEmpty() || rgn.isEmpty() ||
   223                !SkIRect::Intersects(fBounds, rgn.fBounds);
   224     }
   226     /** Translate the region by the specified (dx, dy) amount. */
   227     void translate(int dx, int dy) { this->translate(dx, dy, this); }
   229     /**
   230      *  Translate the region by the specified (dx, dy) amount, writing the
   231      *  resulting region into dst. Note: it is legal to pass this region as the
   232      *  dst parameter, effectively translating the region in place. If dst is
   233      *  null, nothing happens.
   234      */
   235     void translate(int dx, int dy, SkRegion* dst) const;
   237     /**
   238      *  The logical operations that can be performed when combining two regions.
   239      */
   240     enum Op {
   241         kDifference_Op, //!< subtract the op region from the first region
   242         kIntersect_Op,  //!< intersect the two regions
   243         kUnion_Op,      //!< union (inclusive-or) the two regions
   244         kXOR_Op,        //!< exclusive-or the two regions
   245         /** subtract the first region from the op region */
   246         kReverseDifference_Op,
   247         kReplace_Op     //!< replace the dst region with the op region
   248     };
   250     /**
   251      *  Set this region to the result of applying the Op to this region and the
   252      *  specified rectangle: this = (this op rect).
   253      *  Return true if the resulting region is non-empty.
   254      */
   255     bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }
   257     /**
   258      *  Set this region to the result of applying the Op to this region and the
   259      *  specified rectangle: this = (this op rect).
   260      *  Return true if the resulting region is non-empty.
   261      */
   262     bool op(int left, int top, int right, int bottom, Op op) {
   263         SkIRect rect;
   264         rect.set(left, top, right, bottom);
   265         return this->op(*this, rect, op);
   266     }
   268     /**
   269      *  Set this region to the result of applying the Op to this region and the
   270      *  specified region: this = (this op rgn).
   271      *  Return true if the resulting region is non-empty.
   272      */
   273     bool op(const SkRegion& rgn, Op op) { return this->op(*this, rgn, op); }
   275     /**
   276      *  Set this region to the result of applying the Op to the specified
   277      *  rectangle and region: this = (rect op rgn).
   278      *  Return true if the resulting region is non-empty.
   279      */
   280     bool op(const SkIRect& rect, const SkRegion& rgn, Op);
   282     /**
   283      *  Set this region to the result of applying the Op to the specified
   284      *  region and rectangle: this = (rgn op rect).
   285      *  Return true if the resulting region is non-empty.
   286      */
   287     bool op(const SkRegion& rgn, const SkIRect& rect, Op);
   289     /**
   290      *  Set this region to the result of applying the Op to the specified
   291      *  regions: this = (rgna op rgnb).
   292      *  Return true if the resulting region is non-empty.
   293      */
   294     bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
   296 #ifdef SK_BUILD_FOR_ANDROID
   297     /** Returns a new char* containing the list of rectangles in this region
   298      */
   299     char* toString();
   300 #endif
   302     /**
   303      *  Returns the sequence of rectangles, sorted in Y and X, that make up
   304      *  this region.
   305      */
   306     class SK_API Iterator {
   307     public:
   308         Iterator() : fRgn(NULL), fDone(true) {}
   309         Iterator(const SkRegion&);
   310         // if we have a region, reset to it and return true, else return false
   311         bool rewind();
   312         // reset the iterator, using the new region
   313         void reset(const SkRegion&);
   314         bool done() const { return fDone; }
   315         void next();
   316         const SkIRect& rect() const { return fRect; }
   317         // may return null
   318         const SkRegion* rgn() const { return fRgn; }
   320     private:
   321         const SkRegion* fRgn;
   322         const RunType*  fRuns;
   323         SkIRect         fRect;
   324         bool            fDone;
   325     };
   327     /**
   328      *  Returns the sequence of rectangles, sorted in Y and X, that make up
   329      *  this region intersected with the specified clip rectangle.
   330      */
   331     class SK_API Cliperator {
   332     public:
   333         Cliperator(const SkRegion&, const SkIRect& clip);
   334         bool done() { return fDone; }
   335         void  next();
   336         const SkIRect& rect() const { return fRect; }
   338     private:
   339         Iterator    fIter;
   340         SkIRect     fClip;
   341         SkIRect     fRect;
   342         bool        fDone;
   343     };
   345     /**
   346      *  Returns the sequence of runs that make up this region for the specified
   347      *  Y scanline, clipped to the specified left and right X values.
   348      */
   349     class Spanerator {
   350     public:
   351         Spanerator(const SkRegion&, int y, int left, int right);
   352         bool next(int* left, int* right);
   354     private:
   355         const SkRegion::RunType* fRuns;
   356         int     fLeft, fRight;
   357         bool    fDone;
   358     };
   360     /**
   361      *  Write the region to the buffer, and return the number of bytes written.
   362      *  If buffer is NULL, it still returns the number of bytes.
   363      */
   364     size_t writeToMemory(void* buffer) const;
   365     /**
   366      * Initializes the region from the buffer
   367      *
   368      * @param buffer Memory to read from
   369      * @param length Amount of memory available in the buffer
   370      * @return number of bytes read (must be a multiple of 4) or
   371      *         0 if there was not enough memory available
   372      */
   373     size_t readFromMemory(const void* buffer, size_t length);
   375     /**
   376      *  Returns a reference to a global empty region. Just a convenience for
   377      *  callers that need a const empty region.
   378      */
   379     static const SkRegion& GetEmptyRegion();
   381     SkDEBUGCODE(void dump() const;)
   382     SkDEBUGCODE(void validate() const;)
   383     SkDEBUGCODE(static void UnitTest();)
   385     // expose this to allow for regression test on complex regions
   386     SkDEBUGCODE(bool debugSetRuns(const RunType runs[], int count);)
   388 private:
   389     enum {
   390         kOpCount = kReplace_Op + 1
   391     };
   393     enum {
   394         // T
   395         // [B N L R S]
   396         // S
   397         kRectRegionRuns = 7
   398     };
   400     friend class android::Region;    // needed for marshalling efficiently
   402     struct RunHead;
   404     // allocate space for count runs
   405     void allocateRuns(int count);
   406     void allocateRuns(int count, int ySpanCount, int intervalCount);
   407     void allocateRuns(const RunHead& src);
   409     SkIRect     fBounds;
   410     RunHead*    fRunHead;
   412     void freeRuns();
   414     /**
   415      *  Return the runs from this region, consing up fake runs if the region
   416      *  is empty or a rect. In those 2 cases, we use tmpStorage to hold the
   417      *  run data.
   418      */
   419     const RunType*  getRuns(RunType tmpStorage[], int* intervals) const;
   421     // This is called with runs[] that do not yet have their interval-count
   422     // field set on each scanline. That is computed as part of this call
   423     // (inside ComputeRunBounds).
   424     bool setRuns(RunType runs[], int count);
   426     int count_runtype_values(int* itop, int* ibot) const;
   428     static void BuildRectRuns(const SkIRect& bounds,
   429                               RunType runs[kRectRegionRuns]);
   431     // If the runs define a simple rect, return true and set bounds to that
   432     // rect. If not, return false and ignore bounds.
   433     static bool RunsAreARect(const SkRegion::RunType runs[], int count,
   434                              SkIRect* bounds);
   436     /**
   437      *  If the last arg is null, just return if the result is non-empty,
   438      *  else store the result in the last arg.
   439      */
   440     static bool Oper(const SkRegion&, const SkRegion&, SkRegion::Op, SkRegion*);
   442     friend struct RunHead;
   443     friend class Iterator;
   444     friend class Spanerator;
   445     friend class SkRgnBuilder;
   446     friend class SkFlatRegion;
   447 };
   449 #endif

mercurial