Home | History | Annotate | Download | only in core
      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 #include "SkRect.h"
     11 
     12 void SkIRect::join(int32_t left, int32_t top, int32_t right, int32_t bottom) {
     13     // do nothing if the params are empty
     14     if (left >= right || top >= bottom) {
     15         return;
     16     }
     17 
     18     // if we are empty, just assign
     19     if (fLeft >= fRight || fTop >= fBottom) {
     20         this->set(left, top, right, bottom);
     21     } else {
     22         if (left < fLeft) fLeft = left;
     23         if (top < fTop) fTop = top;
     24         if (right > fRight) fRight = right;
     25         if (bottom > fBottom) fBottom = bottom;
     26     }
     27 }
     28 
     29 void SkIRect::sort() {
     30     if (fLeft > fRight) {
     31         SkTSwap<int32_t>(fLeft, fRight);
     32     }
     33     if (fTop > fBottom) {
     34         SkTSwap<int32_t>(fTop, fBottom);
     35     }
     36 }
     37 
     38 /////////////////////////////////////////////////////////////////////////////
     39 
     40 void SkRect::sort() {
     41     if (fLeft > fRight) {
     42         SkTSwap<SkScalar>(fLeft, fRight);
     43     }
     44     if (fTop > fBottom) {
     45         SkTSwap<SkScalar>(fTop, fBottom);
     46     }
     47 }
     48 
     49 void SkRect::toQuad(SkPoint quad[4]) const {
     50     SkASSERT(quad);
     51 
     52     quad[0].set(fLeft, fTop);
     53     quad[1].set(fRight, fTop);
     54     quad[2].set(fRight, fBottom);
     55     quad[3].set(fLeft, fBottom);
     56 }
     57 
     58 #ifdef SK_SCALAR_IS_FLOAT
     59     #define SkFLOATCODE(code)   code
     60 #else
     61     #define SkFLOATCODE(code)
     62 #endif
     63 
     64 void SkRect::set(const SkPoint pts[], int count) {
     65     SkASSERT((pts && count > 0) || count == 0);
     66 
     67     if (count <= 0) {
     68         sk_bzero(this, sizeof(SkRect));
     69     } else {
     70 #ifdef SK_SCALAR_SLOW_COMPARES
     71         int32_t    l, t, r, b;
     72 
     73         l = r = SkScalarAs2sCompliment(pts[0].fX);
     74         t = b = SkScalarAs2sCompliment(pts[0].fY);
     75 
     76         for (int i = 1; i < count; i++) {
     77             int32_t x = SkScalarAs2sCompliment(pts[i].fX);
     78             int32_t y = SkScalarAs2sCompliment(pts[i].fY);
     79 
     80             if (x < l) l = x; else if (x > r) r = x;
     81             if (y < t) t = y; else if (y > b) b = y;
     82         }
     83         this->set(Sk2sComplimentAsScalar(l),
     84                   Sk2sComplimentAsScalar(t),
     85                   Sk2sComplimentAsScalar(r),
     86                   Sk2sComplimentAsScalar(b));
     87 #else
     88         SkScalar    l, t, r, b;
     89         SkFLOATCODE(int isNaN;)
     90 
     91         l = r = pts[0].fX;
     92         t = b = pts[0].fY;
     93         SkFLOATCODE(isNaN = (l != l) | (t != t);)
     94 
     95         for (int i = 1; i < count; i++) {
     96             SkScalar x = pts[i].fX;
     97             SkScalar y = pts[i].fY;
     98             SkFLOATCODE(isNaN |= (x != x) | (y != y);)
     99 
    100             if (x < l) l = x; else if (x > r) r = x;
    101             if (y < t) t = y; else if (y > b) b = y;
    102         }
    103 
    104 #ifdef SK_SCALAR_IS_FLOAT
    105         if (isNaN) {
    106             l = t = r = b = 0;
    107         }
    108 #endif
    109         this->set(l, t, r, b);
    110 #endif
    111     }
    112 }
    113 
    114 bool SkRect::intersect(SkScalar left, SkScalar top, SkScalar right,
    115                        SkScalar bottom) {
    116     if (left < right && top < bottom && !this->isEmpty() && // check for empties
    117         fLeft < right && left < fRight && fTop < bottom && top < fBottom)
    118     {
    119         if (fLeft < left) fLeft = left;
    120         if (fTop < top) fTop = top;
    121         if (fRight > right) fRight = right;
    122         if (fBottom > bottom) fBottom = bottom;
    123         return true;
    124     }
    125     return false;
    126 }
    127 
    128 bool SkRect::intersect(const SkRect& r) {
    129     SkASSERT(&r);
    130     return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
    131 }
    132 
    133 bool SkRect::intersect(const SkRect& a, const SkRect& b) {
    134     SkASSERT(&a && &b);
    135 
    136     if (!a.isEmpty() && !b.isEmpty() &&
    137         a.fLeft < b.fRight && b.fLeft < a.fRight &&
    138         a.fTop < b.fBottom && b.fTop < a.fBottom) {
    139         fLeft   = SkMaxScalar(a.fLeft,   b.fLeft);
    140         fTop    = SkMaxScalar(a.fTop,    b.fTop);
    141         fRight  = SkMinScalar(a.fRight,  b.fRight);
    142         fBottom = SkMinScalar(a.fBottom, b.fBottom);
    143         return true;
    144     }
    145     return false;
    146 }
    147 
    148 void SkRect::join(SkScalar left, SkScalar top, SkScalar right,
    149                   SkScalar bottom) {
    150     // do nothing if the params are empty
    151     if (left >= right || top >= bottom) {
    152         return;
    153     }
    154 
    155     // if we are empty, just assign
    156     if (fLeft >= fRight || fTop >= fBottom) {
    157         this->set(left, top, right, bottom);
    158     } else {
    159         if (left < fLeft) fLeft = left;
    160         if (top < fTop) fTop = top;
    161         if (right > fRight) fRight = right;
    162         if (bottom > fBottom) fBottom = bottom;
    163     }
    164 }
    165 
    166