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

       1                 : 
       2                 : /*
       3                 :  * Copyright 2006 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 SkRect_DEFINED
      11                 : #define SkRect_DEFINED
      12                 : 
      13                 : #include "SkPoint.h"
      14                 : #include "SkSize.h"
      15                 : 
      16                 : /** \struct SkIRect
      17                 : 
      18                 :     SkIRect holds four 32 bit integer coordinates for a rectangle
      19                 : */
      20                 : struct SK_API SkIRect {
      21                 :     int32_t fLeft, fTop, fRight, fBottom;
      22                 : 
      23                 :     static SkIRect MakeEmpty() {
      24                 :         SkIRect r;
      25                 :         r.setEmpty();
      26                 :         return r;
      27                 :     }
      28                 :     
      29               0 :     static SkIRect MakeWH(int32_t w, int32_t h) {
      30                 :         SkIRect r;
      31               0 :         r.set(0, 0, w, h);
      32                 :         return r;
      33                 :     }
      34                 :     
      35                 :     static SkIRect MakeSize(const SkISize& size) {
      36                 :         SkIRect r;
      37                 :         r.set(0, 0, size.width(), size.height());
      38                 :         return r;
      39                 :     }
      40                 :     
      41               0 :     static SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
      42                 :         SkIRect rect;
      43               0 :         rect.set(l, t, r, b);
      44                 :         return rect;
      45                 :     }
      46                 :     
      47               0 :     static SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
      48                 :         SkIRect r;
      49               0 :         r.set(x, y, x + w, y + h);
      50                 :         return r;
      51                 :     }
      52                 : 
      53               0 :     int left() const { return fLeft; }
      54               0 :     int top() const { return fTop; }
      55                 :     int right() const { return fRight; }
      56                 :     int bottom() const { return fBottom; }
      57                 :     
      58                 :     /** return the left edge of the rect */
      59               0 :     int x() const { return fLeft; }
      60                 :     /** return the top edge of the rect */
      61               0 :     int y() const { return fTop; }
      62                 :     /**
      63                 :      *  Returns the rectangle's width. This does not check for a valid rect
      64                 :      *  (i.e. left <= right) so the result may be negative.
      65                 :      */
      66               0 :     int width() const { return fRight - fLeft; }
      67                 :     
      68                 :     /**
      69                 :      *  Returns the rectangle's height. This does not check for a valid rect
      70                 :      *  (i.e. top <= bottom) so the result may be negative.
      71                 :      */
      72               0 :     int height() const { return fBottom - fTop; }
      73                 :     
      74                 :     /**
      75                 :      *  Return true if the rectangle's width or height are <= 0
      76                 :      */
      77               0 :     bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
      78                 : 
      79               0 :     friend bool operator==(const SkIRect& a, const SkIRect& b) {
      80               0 :         return !memcmp(&a, &b, sizeof(a));
      81                 :     }
      82                 : 
      83               0 :     friend bool operator!=(const SkIRect& a, const SkIRect& b) {
      84               0 :         return !(a == b);
      85                 :     }
      86                 : 
      87               0 :     bool is16Bit() const {
      88               0 :         return  SkIsS16(fLeft) && SkIsS16(fTop) &&
      89               0 :                 SkIsS16(fRight) && SkIsS16(fBottom);
      90                 :     }
      91                 : 
      92                 :     /** Set the rectangle to (0,0,0,0)
      93                 :     */
      94               0 :     void setEmpty() { memset(this, 0, sizeof(*this)); }
      95                 : 
      96               0 :     void set(int32_t left, int32_t top, int32_t right, int32_t bottom) {
      97               0 :         fLeft   = left;
      98               0 :         fTop    = top;
      99               0 :         fRight  = right;
     100               0 :         fBottom = bottom;
     101               0 :     }
     102                 :     // alias for set(l, t, r, b)
     103                 :     void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) {
     104                 :         this->set(left, top, right, bottom);
     105                 :     }
     106                 : 
     107               0 :     void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) {
     108               0 :         fLeft = x;
     109               0 :         fTop = y;
     110               0 :         fRight = x + width;
     111               0 :         fBottom = y + height;
     112               0 :     }
     113                 : 
     114                 :     /**
     115                 :      *  Make the largest representable rectangle
     116                 :      */
     117                 :     void setLargest() {
     118                 :         fLeft = fTop = SK_MinS32;
     119                 :         fRight = fBottom = SK_MaxS32;
     120                 :     }
     121                 :     
     122                 :     /**
     123                 :      *  Make the largest representable rectangle, but inverted (e.g. fLeft will
     124                 :      *  be max 32bit and right will be min 32bit).
     125                 :      */
     126                 :     void setLargestInverted() {
     127                 :         fLeft = fTop = SK_MaxS32;
     128                 :         fRight = fBottom = SK_MinS32;
     129                 :     }
     130                 :     
     131                 :     /** Offset set the rectangle by adding dx to its left and right,
     132                 :         and adding dy to its top and bottom.
     133                 :     */
     134               0 :     void offset(int32_t dx, int32_t dy) {
     135               0 :         fLeft   += dx;
     136               0 :         fTop    += dy;
     137               0 :         fRight  += dx;
     138               0 :         fBottom += dy;
     139               0 :     }
     140                 : 
     141                 :     void offset(const SkIPoint& delta) {
     142                 :         this->offset(delta.fX, delta.fY);
     143                 :     }
     144                 : 
     145                 :     /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
     146                 :         making the rectangle narrower. If dx is negative, then the sides are moved outwards,
     147                 :         making the rectangle wider. The same hods true for dy and the top and bottom.
     148                 :     */
     149               0 :     void inset(int32_t dx, int32_t dy) {
     150               0 :         fLeft   += dx;
     151               0 :         fTop    += dy;
     152               0 :         fRight  -= dx;
     153               0 :         fBottom -= dy;
     154               0 :     }
     155                 : 
     156                 :     bool quickReject(int l, int t, int r, int b) const {
     157                 :         return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
     158                 :     }
     159                 :     
     160                 :     /** Returns true if (x,y) is inside the rectangle and the rectangle is not
     161                 :         empty. The left and top are considered to be inside, while the right
     162                 :         and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
     163                 :         points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not.
     164                 :     */
     165               0 :     bool contains(int32_t x, int32_t y) const {
     166                 :         return  (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) &&
     167               0 :                 (unsigned)(y - fTop) < (unsigned)(fBottom - fTop);
     168                 :     }
     169                 : 
     170                 :     /** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle.
     171                 :         If either rectangle is empty, contains() returns false.
     172                 :     */
     173               0 :     bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const {
     174               0 :         return  left < right && top < bottom && !this->isEmpty() && // check for empties
     175                 :                 fLeft <= left && fTop <= top &&
     176               0 :                 fRight >= right && fBottom >= bottom;
     177                 :     }
     178                 : 
     179                 :     /** Returns true if the specified rectangle r is inside or equal to this rectangle.
     180                 :     */
     181               0 :     bool contains(const SkIRect& r) const {
     182               0 :         return  !r.isEmpty() && !this->isEmpty() &&     // check for empties
     183                 :                 fLeft <= r.fLeft && fTop <= r.fTop &&
     184               0 :                 fRight >= r.fRight && fBottom >= r.fBottom;
     185                 :     }
     186                 : 
     187                 :     /** Return true if this rectangle contains the specified rectangle.
     188                 :                 For speed, this method does not check if either this or the specified
     189                 :                 rectangles are empty, and if either is, its return value is undefined.
     190                 :                 In the debugging build however, we assert that both this and the
     191                 :                 specified rectangles are non-empty.
     192                 :     */
     193               0 :     bool containsNoEmptyCheck(int32_t left, int32_t top,
     194                 :                                                           int32_t right, int32_t bottom) const {
     195               0 :                 SkASSERT(fLeft < fRight && fTop < fBottom);
     196               0 :         SkASSERT(left < right && top < bottom);
     197                 : 
     198                 :         return fLeft <= left && fTop <= top &&
     199               0 :                            fRight >= right && fBottom >= bottom;
     200                 :     }
     201                 :     
     202                 :     /** If r intersects this rectangle, return true and set this rectangle to that
     203                 :         intersection, otherwise return false and do not change this rectangle.
     204                 :         If either rectangle is empty, do nothing and return false.
     205                 :     */
     206               0 :     bool intersect(const SkIRect& r) {
     207               0 :         SkASSERT(&r);
     208               0 :         return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
     209                 :     }
     210                 : 
     211                 :     /** If rectangles a and b intersect, return true and set this rectangle to
     212                 :         that intersection, otherwise return false and do not change this
     213                 :         rectangle. If either rectangle is empty, do nothing and return false.
     214                 :     */
     215               0 :     bool intersect(const SkIRect& a, const SkIRect& b) {
     216               0 :         SkASSERT(&a && &b);
     217                 :         
     218               0 :         if (!a.isEmpty() && !b.isEmpty() &&
     219                 :                 a.fLeft < b.fRight && b.fLeft < a.fRight &&
     220                 :                 a.fTop < b.fBottom && b.fTop < a.fBottom) {
     221               0 :             fLeft   = SkMax32(a.fLeft,   b.fLeft);
     222               0 :             fTop    = SkMax32(a.fTop,    b.fTop);
     223               0 :             fRight  = SkMin32(a.fRight,  b.fRight);
     224               0 :             fBottom = SkMin32(a.fBottom, b.fBottom);
     225               0 :             return true;
     226                 :         }
     227               0 :         return false;
     228                 :     }
     229                 :     
     230                 :     /** If rectangles a and b intersect, return true and set this rectangle to
     231                 :         that intersection, otherwise return false and do not change this
     232                 :         rectangle. For speed, no check to see if a or b are empty is performed.
     233                 :         If either is, then the return result is undefined. In the debug build,
     234                 :         we assert that both rectangles are non-empty.
     235                 :     */
     236               0 :     bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) {
     237               0 :         SkASSERT(&a && &b);
     238               0 :         SkASSERT(!a.isEmpty() && !b.isEmpty());
     239                 :         
     240               0 :         if (a.fLeft < b.fRight && b.fLeft < a.fRight &&
     241                 :                 a.fTop < b.fBottom && b.fTop < a.fBottom) {
     242               0 :             fLeft   = SkMax32(a.fLeft,   b.fLeft);
     243               0 :             fTop    = SkMax32(a.fTop,    b.fTop);
     244               0 :             fRight  = SkMin32(a.fRight,  b.fRight);
     245               0 :             fBottom = SkMin32(a.fBottom, b.fBottom);
     246               0 :             return true;
     247                 :         }
     248               0 :         return false;
     249                 :     }
     250                 : 
     251                 :     /** If the rectangle specified by left,top,right,bottom intersects this rectangle,
     252                 :         return true and set this rectangle to that intersection,
     253                 :         otherwise return false and do not change this rectangle.
     254                 :         If either rectangle is empty, do nothing and return false.
     255                 :     */
     256               0 :     bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
     257               0 :         if (left < right && top < bottom && !this->isEmpty() &&
     258                 :                 fLeft < right && left < fRight && fTop < bottom && top < fBottom) {
     259               0 :             if (fLeft < left) fLeft = left;
     260               0 :             if (fTop < top) fTop = top;
     261               0 :             if (fRight > right) fRight = right;
     262               0 :             if (fBottom > bottom) fBottom = bottom;
     263               0 :             return true;
     264                 :         }
     265               0 :         return false;
     266                 :     }
     267                 :     
     268                 :     /** Returns true if a and b are not empty, and they intersect
     269                 :     */
     270               0 :     static bool Intersects(const SkIRect& a, const SkIRect& b) {
     271               0 :         return  !a.isEmpty() && !b.isEmpty() &&              // check for empties
     272                 :                 a.fLeft < b.fRight && b.fLeft < a.fRight &&
     273               0 :                 a.fTop < b.fBottom && b.fTop < a.fBottom;
     274                 :     }
     275                 :     
     276                 :     /** Update this rectangle to enclose itself and the specified rectangle.
     277                 :         If this rectangle is empty, just set it to the specified rectangle. If the specified
     278                 :         rectangle is empty, do nothing.
     279                 :     */
     280                 :     void join(int32_t left, int32_t top, int32_t right, int32_t bottom);
     281                 : 
     282                 :     /** Update this rectangle to enclose itself and the specified rectangle.
     283                 :         If this rectangle is empty, just set it to the specified rectangle. If the specified
     284                 :         rectangle is empty, do nothing.
     285                 :     */
     286               0 :     void join(const SkIRect& r) {
     287               0 :         this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
     288               0 :     }
     289                 : 
     290                 :     /** Swap top/bottom or left/right if there are flipped.
     291                 :         This can be called if the edges are computed separately,
     292                 :         and may have crossed over each other.
     293                 :         When this returns, left <= right && top <= bottom
     294                 :     */
     295                 :     void sort();
     296                 : 
     297                 :     static const SkIRect& EmptyIRect() {
     298                 :         static const SkIRect gEmpty = { 0, 0, 0, 0 };
     299                 :         return gEmpty;
     300                 :     }
     301                 : };
     302                 : 
     303                 : /** \struct SkRect
     304                 : */
     305                 : struct SK_API SkRect {
     306                 :     SkScalar    fLeft, fTop, fRight, fBottom;
     307                 : 
     308                 :     static SkRect MakeEmpty() {
     309                 :         SkRect r;
     310                 :         r.setEmpty();
     311                 :         return r;
     312                 :     }
     313                 : 
     314                 :     static SkRect MakeWH(SkScalar w, SkScalar h) {
     315                 :         SkRect r;
     316                 :         r.set(0, 0, w, h);
     317                 :         return r;
     318                 :     }
     319                 : 
     320                 :     static SkRect MakeSize(const SkSize& size) {
     321                 :         SkRect r;
     322                 :         r.set(0, 0, size.width(), size.height());
     323                 :         return r;
     324                 :     }
     325                 : 
     326                 :     static SkRect MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
     327                 :         SkRect rect;
     328                 :         rect.set(l, t, r, b);
     329                 :         return rect;
     330                 :     }
     331                 : 
     332                 :     static SkRect MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) {
     333                 :         SkRect r;
     334                 :         r.set(x, y, x + w, y + h);
     335                 :         return r;
     336                 :     }
     337                 : 
     338                 :     /**
     339                 :      *  Return true if the rectangle's width or height are <= 0
     340                 :      */
     341               0 :     bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
     342                 :     
     343                 :     /**
     344                 :      *  Returns true iff all values in the rect are finite. If any are
     345                 :      *  infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this
     346                 :      *  returns false.
     347                 :      */
     348               0 :     bool isFinite() const {
     349                 : #ifdef SK_SCALAR_IS_FLOAT
     350                 :         // x * 0 will be NaN iff x is infinity or NaN.
     351                 :         // a + b will be NaN iff either a or b is NaN.
     352               0 :         float value = fLeft * 0 + fTop * 0 + fRight * 0 + fBottom * 0;
     353                 :         
     354                 :         // value is either NaN or it is finite (zero).
     355                 :         // value==value will be true iff value is not NaN
     356               0 :         return value == value;
     357                 : #else
     358                 :         // use bit-or for speed, since we don't care about short-circuting the
     359                 :         // tests, and we expect the common case will be that we need to check all.
     360                 :         int isNaN = (SK_FixedNaN == fLeft)  | (SK_FixedNaN == fTop) |
     361                 :                     (SK_FixedNaN == fRight) | (SK_FixedNaN == fBottom);
     362                 :         return !isNaN;
     363                 : #endif
     364                 :     }
     365                 : 
     366                 :     SkScalar    left() const { return fLeft; }
     367                 :     SkScalar    top() const { return fTop; }
     368                 :     SkScalar    right() const { return fRight; }
     369                 :     SkScalar    bottom() const { return fBottom; }
     370               0 :     SkScalar    width() const { return fRight - fLeft; }
     371               0 :     SkScalar    height() const { return fBottom - fTop; }
     372               0 :     SkScalar    centerX() const { return SkScalarHalf(fLeft + fRight); }
     373               0 :     SkScalar    centerY() const { return SkScalarHalf(fTop + fBottom); }
     374                 : 
     375               0 :     friend bool operator==(const SkRect& a, const SkRect& b) {
     376               0 :         return 0 == memcmp(&a, &b, sizeof(a));
     377                 :     }
     378                 : 
     379                 :     friend bool operator!=(const SkRect& a, const SkRect& b) {
     380                 :         return 0 != memcmp(&a, &b, sizeof(a));
     381                 :     }
     382                 : 
     383                 :     /** return the 4 points that enclose the rectangle
     384                 :     */
     385                 :     void toQuad(SkPoint quad[4]) const;
     386                 : 
     387                 :     /** Set this rectangle to the empty rectangle (0,0,0,0)
     388                 :     */
     389               0 :     void setEmpty() { memset(this, 0, sizeof(*this)); }
     390                 : 
     391               0 :     void set(const SkIRect& src) {
     392               0 :         fLeft   = SkIntToScalar(src.fLeft);
     393               0 :         fTop    = SkIntToScalar(src.fTop);
     394               0 :         fRight  = SkIntToScalar(src.fRight);
     395               0 :         fBottom = SkIntToScalar(src.fBottom);
     396               0 :     }
     397                 : 
     398               0 :     void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
     399               0 :         fLeft   = left;
     400               0 :         fTop    = top;
     401               0 :         fRight  = right;
     402               0 :         fBottom = bottom;
     403               0 :     }
     404                 :     // alias for set(l, t, r, b)
     405                 :     void setLTRB(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
     406                 :         this->set(left, top, right, bottom);
     407                 :     }
     408                 : 
     409                 :     /** Initialize the rect with the 4 specified integers. The routine handles
     410                 :         converting them to scalars (by calling SkIntToScalar)
     411                 :      */
     412               0 :     void iset(int left, int top, int right, int bottom) {
     413               0 :         fLeft   = SkIntToScalar(left);
     414               0 :         fTop    = SkIntToScalar(top);
     415               0 :         fRight  = SkIntToScalar(right);
     416               0 :         fBottom = SkIntToScalar(bottom);
     417               0 :     }
     418                 : 
     419                 :     /** Set this rectangle to be the bounds of the array of points.
     420                 :         If the array is empty (count == 0), then set this rectangle
     421                 :         to the empty rectangle (0,0,0,0)
     422                 :     */
     423                 :     void set(const SkPoint pts[], int count);
     424                 : 
     425                 :     // alias for set(pts, count)
     426                 :     void setBounds(const SkPoint pts[], int count) {
     427                 :         this->set(pts, count);
     428                 :     }
     429                 : 
     430                 :     void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) {
     431                 :         fLeft = x;
     432                 :         fTop = y;
     433                 :         fRight = x + width;
     434                 :         fBottom = y + height;
     435                 :     }
     436                 : 
     437                 :     /**
     438                 :      *  Make the largest representable rectangle
     439                 :      */
     440                 :     void setLargest() {
     441                 :         fLeft = fTop = SK_ScalarMin;
     442                 :         fRight = fBottom = SK_ScalarMax;
     443                 :     }
     444                 :     
     445                 :     /**
     446                 :      *  Make the largest representable rectangle, but inverted (e.g. fLeft will
     447                 :      *  be max and right will be min).
     448                 :      */
     449                 :     void setLargestInverted() {
     450                 :         fLeft = fTop = SK_ScalarMax;
     451                 :         fRight = fBottom = SK_ScalarMin;
     452                 :     }
     453                 : 
     454                 :     /** Offset set the rectangle by adding dx to its left and right,
     455                 :         and adding dy to its top and bottom.
     456                 :     */
     457               0 :     void offset(SkScalar dx, SkScalar dy) {
     458               0 :         fLeft   += dx;
     459               0 :         fTop    += dy;
     460               0 :         fRight  += dx;
     461               0 :         fBottom += dy;
     462               0 :     }   
     463                 : 
     464                 :     void offset(const SkPoint& delta) {
     465                 :         this->offset(delta.fX, delta.fY);
     466                 :     }
     467                 : 
     468                 :     /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are
     469                 :         moved inwards, making the rectangle narrower. If dx is negative, then
     470                 :         the sides are moved outwards, making the rectangle wider. The same holds
     471                 :          true for dy and the top and bottom.
     472                 :     */
     473               0 :     void inset(SkScalar dx, SkScalar dy)  {
     474               0 :         fLeft   += dx;
     475               0 :         fTop    += dy;
     476               0 :         fRight  -= dx;
     477               0 :         fBottom -= dy;
     478               0 :     }
     479                 : 
     480                 :    /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
     481                 :        moved outwards, making the rectangle wider. If dx is negative, then the
     482                 :        sides are moved inwards, making the rectangle narrower. The same hods
     483                 :        true for dy and the top and bottom.
     484                 :     */
     485                 :     void outset(SkScalar dx, SkScalar dy)  { this->inset(-dx, -dy); }
     486                 : 
     487                 :     /** If this rectangle intersects r, return true and set this rectangle to that
     488                 :         intersection, otherwise return false and do not change this rectangle.
     489                 :         If either rectangle is empty, do nothing and return false.
     490                 :     */
     491                 :     bool intersect(const SkRect& r);
     492                 : 
     493                 :     /** If this rectangle intersects the rectangle specified by left, top, right, bottom,
     494                 :         return true and set this rectangle to that intersection, otherwise return false
     495                 :         and do not change this rectangle.
     496                 :         If either rectangle is empty, do nothing and return false.
     497                 :     */
     498                 :     bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
     499                 : 
     500                 :     /**
     501                 :      *  Return true if this rectangle is not empty, and the specified sides of
     502                 :      *  a rectangle are not empty, and they intersect.
     503                 :      */
     504                 :     bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const {
     505                 :         return // first check that both are not empty
     506                 :                left < right && top < bottom &&
     507                 :                fLeft < fRight && fTop < fBottom &&
     508                 :                // now check for intersection
     509                 :                fLeft < right && left < fRight &&
     510                 :                fTop < bottom && top < fBottom;
     511                 :     }
     512                 : 
     513                 :     /** If rectangles a and b intersect, return true and set this rectangle to
     514                 :      *  that intersection, otherwise return false and do not change this
     515                 :      *  rectangle. If either rectangle is empty, do nothing and return false.
     516                 :      */
     517                 :     bool intersect(const SkRect& a, const SkRect& b);
     518                 :     
     519                 :     /**
     520                 :      *  Return true if rectangles a and b are not empty and intersect.
     521                 :      */
     522               0 :     static bool Intersects(const SkRect& a, const SkRect& b) {
     523               0 :         return  !a.isEmpty() && !b.isEmpty() &&
     524                 :                 a.fLeft < b.fRight && b.fLeft < a.fRight &&
     525               0 :                 a.fTop < b.fBottom && b.fTop < a.fBottom;
     526                 :     }
     527                 :     
     528                 :     /**
     529                 :      *  Update this rectangle to enclose itself and the specified rectangle.
     530                 :      *  If this rectangle is empty, just set it to the specified rectangle.
     531                 :      *  If the specified rectangle is empty, do nothing.
     532                 :      */
     533                 :     void join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom);
     534                 : 
     535                 :     /** Update this rectangle to enclose itself and the specified rectangle.
     536                 :         If this rectangle is empty, just set it to the specified rectangle. If the specified
     537                 :         rectangle is empty, do nothing.
     538                 :     */
     539                 :     void join(const SkRect& r) {
     540                 :         this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
     541                 :     }
     542                 :     // alias for join()
     543                 :     void growToInclude(const SkRect& r) { this->join(r); }
     544                 : 
     545                 :     /**
     546                 :      *  Grow the rect to include the specified (x,y). After this call, the
     547                 :      *  following will be true: fLeft <= x <= fRight && fTop <= y <= fBottom.
     548                 :      *
     549                 :      *  This is close, but not quite the same contract as contains(), since
     550                 :      *  contains() treats the left and top different from the right and bottom.
     551                 :      *  contains(x,y) -> fLeft <= x < fRight && fTop <= y < fBottom. Also note
     552                 :      *  that contains(x,y) always returns false if the rect is empty.
     553                 :      */
     554                 :     void growToInclude(SkScalar x, SkScalar y) {
     555                 :         fLeft  = SkMinScalar(x, fLeft);
     556                 :         fRight = SkMaxScalar(x, fRight);
     557                 :         fTop    = SkMinScalar(y, fTop);
     558                 :         fBottom = SkMaxScalar(y, fBottom);
     559                 :     }
     560                 :     
     561                 :     /**
     562                 :      *  Returns true if (p.fX,p.fY) is inside the rectangle, and the rectangle
     563                 :      *  is not empty.
     564                 :      *
     565                 :      *  Contains treats the left and top differently from the right and bottom.
     566                 :      *  The left and top coordinates of the rectangle are themselves considered
     567                 :      *  to be inside, while the right and bottom are not. Thus for the rectangle
     568                 :      *  {0, 0, 5, 10}, (0,0) is contained, but (0,10), (5,0) and (5,10) are not.
     569                 :      */
     570                 :     bool contains(const SkPoint& p) const {
     571                 :         return !this->isEmpty() &&
     572                 :                fLeft <= p.fX && p.fX < fRight && fTop <= p.fY && p.fY < fBottom;
     573                 :     }
     574                 : 
     575                 :     /**
     576                 :      *  Returns true if (x,y) is inside the rectangle, and the rectangle
     577                 :      *  is not empty.
     578                 :      *
     579                 :      *  Contains treats the left and top differently from the right and bottom.
     580                 :      *  The left and top coordinates of the rectangle are themselves considered
     581                 :      *  to be inside, while the right and bottom are not. Thus for the rectangle
     582                 :      *  {0, 0, 5, 10}, (0,0) is contained, but (0,10), (5,0) and (5,10) are not.
     583                 :      */
     584                 :     bool contains(SkScalar x, SkScalar y) const {
     585                 :         return  !this->isEmpty() &&
     586                 :                 fLeft <= x && x < fRight && fTop <= y && y < fBottom;
     587                 :     }
     588                 : 
     589                 :     /**
     590                 :      *  Return true if this rectangle contains r, and if both rectangles are
     591                 :      *  not empty.
     592                 :      */
     593               0 :     bool contains(const SkRect& r) const {
     594               0 :         return  !r.isEmpty() && !this->isEmpty() &&
     595                 :                 fLeft <= r.fLeft && fTop <= r.fTop &&
     596               0 :                 fRight >= r.fRight && fBottom >= r.fBottom;
     597                 :     }
     598                 : 
     599                 :     /**
     600                 :      *  Set the dst rectangle by rounding this rectangle's coordinates to their
     601                 :      *  nearest integer values using SkScalarRound.
     602                 :      */
     603               0 :     void round(SkIRect* dst) const {
     604               0 :         SkASSERT(dst);
     605               0 :         dst->set(SkScalarRound(fLeft), SkScalarRound(fTop),
     606               0 :                  SkScalarRound(fRight), SkScalarRound(fBottom));
     607               0 :     }
     608                 : 
     609                 :     /**
     610                 :      *  Set the dst rectangle by rounding "out" this rectangle, choosing the
     611                 :      *  SkScalarFloor of top and left, and the SkScalarCeil of right and bottom.
     612                 :      */
     613               0 :     void roundOut(SkIRect* dst) const {
     614               0 :         SkASSERT(dst);
     615               0 :         dst->set(SkScalarFloor(fLeft), SkScalarFloor(fTop),
     616               0 :                  SkScalarCeil(fRight), SkScalarCeil(fBottom));
     617               0 :     }
     618                 : 
     619                 :     /**
     620                 :      *  Expand this rectangle by rounding its coordinates "out", choosing the
     621                 :      *  floor of top and left, and the ceil of right and bottom. If this rect
     622                 :      *  is already on integer coordinates, then it will be unchanged.
     623                 :      */
     624                 :     void roundOut() {
     625                 :         this->set(SkScalarFloorToScalar(fLeft),
     626                 :                   SkScalarFloorToScalar(fTop),
     627                 :                   SkScalarCeilToScalar(fRight),
     628                 :                   SkScalarCeilToScalar(fBottom));
     629                 :     }
     630                 : 
     631                 :     /**
     632                 :      *  Swap top/bottom or left/right if there are flipped (i.e. if width()
     633                 :      *  or height() would have returned a negative value.) This should be called
     634                 :      *  if the edges are computed separately, and may have crossed over each
     635                 :      *  other. When this returns, left <= right && top <= bottom
     636                 :      */
     637                 :     void sort();
     638                 : };
     639                 : 
     640                 : #endif
     641                 : 

Generated by: LCOV version 1.7