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