michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #include "SkRect.h" michael@0: michael@0: void SkIRect::join(int32_t left, int32_t top, int32_t right, int32_t bottom) { michael@0: // do nothing if the params are empty michael@0: if (left >= right || top >= bottom) { michael@0: return; michael@0: } michael@0: michael@0: // if we are empty, just assign michael@0: if (fLeft >= fRight || fTop >= fBottom) { michael@0: this->set(left, top, right, bottom); michael@0: } else { michael@0: if (left < fLeft) fLeft = left; michael@0: if (top < fTop) fTop = top; michael@0: if (right > fRight) fRight = right; michael@0: if (bottom > fBottom) fBottom = bottom; michael@0: } michael@0: } michael@0: michael@0: void SkIRect::sort() { michael@0: if (fLeft > fRight) { michael@0: SkTSwap(fLeft, fRight); michael@0: } michael@0: if (fTop > fBottom) { michael@0: SkTSwap(fTop, fBottom); michael@0: } michael@0: } michael@0: michael@0: ///////////////////////////////////////////////////////////////////////////// michael@0: michael@0: void SkRect::sort() { michael@0: if (fLeft > fRight) { michael@0: SkTSwap(fLeft, fRight); michael@0: } michael@0: if (fTop > fBottom) { michael@0: SkTSwap(fTop, fBottom); michael@0: } michael@0: } michael@0: michael@0: void SkRect::toQuad(SkPoint quad[4]) const { michael@0: SkASSERT(quad); michael@0: michael@0: quad[0].set(fLeft, fTop); michael@0: quad[1].set(fRight, fTop); michael@0: quad[2].set(fRight, fBottom); michael@0: quad[3].set(fLeft, fBottom); michael@0: } michael@0: michael@0: bool SkRect::setBoundsCheck(const SkPoint pts[], int count) { michael@0: SkASSERT((pts && count > 0) || count == 0); michael@0: michael@0: bool isFinite = true; michael@0: michael@0: if (count <= 0) { michael@0: sk_bzero(this, sizeof(SkRect)); michael@0: } else { michael@0: SkScalar l, t, r, b; michael@0: michael@0: l = r = pts[0].fX; michael@0: t = b = pts[0].fY; michael@0: michael@0: // If all of the points are finite, accum should stay 0. If we encounter michael@0: // a NaN or infinity, then accum should become NaN. michael@0: float accum = 0; michael@0: accum *= l; accum *= t; michael@0: michael@0: for (int i = 1; i < count; i++) { michael@0: SkScalar x = pts[i].fX; michael@0: SkScalar y = pts[i].fY; michael@0: michael@0: accum *= x; accum *= y; michael@0: michael@0: // we use if instead of if/else, so we can generate min/max michael@0: // float instructions (at least on SSE) michael@0: if (x < l) l = x; michael@0: if (x > r) r = x; michael@0: michael@0: if (y < t) t = y; michael@0: if (y > b) b = y; michael@0: } michael@0: michael@0: SkASSERT(!accum || !SkScalarIsFinite(accum)); michael@0: if (accum) { michael@0: l = t = r = b = 0; michael@0: isFinite = false; michael@0: } michael@0: this->set(l, t, r, b); michael@0: } michael@0: michael@0: return isFinite; michael@0: } michael@0: michael@0: bool SkRect::intersect(SkScalar left, SkScalar top, SkScalar right, michael@0: SkScalar bottom) { michael@0: if (left < right && top < bottom && !this->isEmpty() && // check for empties michael@0: fLeft < right && left < fRight && fTop < bottom && top < fBottom) michael@0: { michael@0: if (fLeft < left) fLeft = left; michael@0: if (fTop < top) fTop = top; michael@0: if (fRight > right) fRight = right; michael@0: if (fBottom > bottom) fBottom = bottom; michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: bool SkRect::intersect(const SkRect& r) { michael@0: SkASSERT(&r); michael@0: return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); michael@0: } michael@0: michael@0: bool SkRect::intersect2(const SkRect& r) { michael@0: SkASSERT(&r); michael@0: SkScalar L = SkMaxScalar(fLeft, r.fLeft); michael@0: SkScalar R = SkMinScalar(fRight, r.fRight); michael@0: if (L >= R) { michael@0: return false; michael@0: } michael@0: SkScalar T = SkMaxScalar(fTop, r.fTop); michael@0: SkScalar B = SkMinScalar(fBottom, r.fBottom); michael@0: if (T >= B) { michael@0: return false; michael@0: } michael@0: this->set(L, T, R, B); michael@0: return true; michael@0: } michael@0: michael@0: bool SkRect::intersect(const SkRect& a, const SkRect& b) { michael@0: SkASSERT(&a && &b); michael@0: michael@0: if (!a.isEmpty() && !b.isEmpty() && michael@0: a.fLeft < b.fRight && b.fLeft < a.fRight && michael@0: a.fTop < b.fBottom && b.fTop < a.fBottom) { michael@0: fLeft = SkMaxScalar(a.fLeft, b.fLeft); michael@0: fTop = SkMaxScalar(a.fTop, b.fTop); michael@0: fRight = SkMinScalar(a.fRight, b.fRight); michael@0: fBottom = SkMinScalar(a.fBottom, b.fBottom); michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: void SkRect::join(SkScalar left, SkScalar top, SkScalar right, michael@0: SkScalar bottom) { michael@0: // do nothing if the params are empty michael@0: if (left >= right || top >= bottom) { michael@0: return; michael@0: } michael@0: michael@0: // if we are empty, just assign michael@0: if (fLeft >= fRight || fTop >= fBottom) { michael@0: this->set(left, top, right, bottom); michael@0: } else { michael@0: if (left < fLeft) fLeft = left; michael@0: if (top < fTop) fTop = top; michael@0: if (right > fRight) fRight = right; michael@0: if (bottom > fBottom) fBottom = bottom; michael@0: } michael@0: }