SkRect.h revision 363e546ed626b6dbbc42f5db87b3594bc0b5944b
1bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 2bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/* 3bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Copyright 2006 The Android Open Source Project 4bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * 5bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Use of this source code is governed by a BSD-style license that can be 6bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * found in the LICENSE file. 7bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 8bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 10bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifndef SkRect_DEFINED 11bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define SkRect_DEFINED 12bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 13bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkPoint.h" 14bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkSize.h" 15bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 16bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/** \struct SkIRect 17bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 18bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIRect holds four 32 bit integer coordinates for a rectangle 19bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com*/ 20bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstruct SK_API SkIRect { 21bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int32_t fLeft, fTop, fRight, fBottom; 22bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 23b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com static SkIRect SK_WARN_UNUSED_RESULT MakeEmpty() { 24bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIRect r; 25bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.setEmpty(); 26bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 2797c4201c2ce2cad089d7a7edbf405bf2cbdf5329reed@android.com } 28cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com 29bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h) { 30bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIRect r; 31bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.set(0, 0, w, h); 32bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 33bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 34bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 35bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size) { 36bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIRect r; 37bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.set(0, 0, size.width(), size.height()); 38bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 39bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 40bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 41bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) { 42bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIRect rect; 43bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rect.set(l, t, r, b); 44bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return rect; 45bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 46bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 47bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) { 48bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIRect r; 49bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.set(x, y, x + w, y + h); 50bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 51bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 52bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 53bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int left() const { return fLeft; } 54bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int top() const { return fTop; } 55bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int right() const { return fRight; } 56bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int bottom() const { return fBottom; } 57bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 58bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** return the left edge of the rect */ 59bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int x() const { return fLeft; } 60bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** return the top edge of the rect */ 61bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int y() const { return fTop; } 62bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 63bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Returns the rectangle's width. This does not check for a valid rect 64bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * (i.e. left <= right) so the result may be negative. 65bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 66bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int width() const { return fRight - fLeft; } 67bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 68bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 69bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Returns the rectangle's height. This does not check for a valid rect 70bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * (i.e. top <= bottom) so the result may be negative. 71bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 72bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int height() const { return fBottom - fTop; } 73bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 74bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 75bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Since the center of an integer rect may fall on a factional value, this 76bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * method is defined to return (right + left) >> 1. 77bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * 78bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * This is a specific "truncation" of the average, which is different than 79bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * (right + left) / 2 when the sum is negative. 80bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 81bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int centerX() const { return (fRight + fLeft) >> 1; } 82bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 83bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 84bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Since the center of an integer rect may fall on a factional value, this 85bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * method is defined to return (bottom + top) >> 1 86bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * 87bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * This is a specific "truncation" of the average, which is different than 88bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * (bottom + top) / 2 when the sum is negative. 89bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 90bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int centerY() const { return (fBottom + fTop) >> 1; } 91bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 92bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 93bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Return true if the rectangle's width or height are <= 0 94bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 95bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } 96bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 97bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com friend bool operator==(const SkIRect& a, const SkIRect& b) { 98bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return !memcmp(&a, &b, sizeof(a)); 99bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 100bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 101bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com friend bool operator!=(const SkIRect& a, const SkIRect& b) { 102bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return !(a == b); 103bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 104bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 105bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool is16Bit() const { 106bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return SkIsS16(fLeft) && SkIsS16(fTop) && 107bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIsS16(fRight) && SkIsS16(fBottom); 108bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 109bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 110bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Set the rectangle to (0,0,0,0) 111bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 112bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void setEmpty() { memset(this, 0, sizeof(*this)); } 113bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void set(int32_t left, int32_t top, int32_t right, int32_t bottom) { 115bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = left; 116bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = top; 117bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight = right; 118bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom = bottom; 119bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // alias for set(l, t, r, b) 121bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) { 122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->set(left, top, right, bottom); 123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 125bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) { 126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = x; 127bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = y; 128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight = x + width; 129bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom = y + height; 130c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com } 131c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com 132bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 133bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Make the largest representable rectangle 134bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 135c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com void setLargest() { 136bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = fTop = SK_MinS32; 137bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight = fBottom = SK_MaxS32; 138bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 139bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 140bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 141bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Make the largest representable rectangle, but inverted (e.g. fLeft will 142bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * be max 32bit and right will be min 32bit). 143bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 144bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void setLargestInverted() { 145bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = fTop = SK_MaxS32; 146bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight = fBottom = SK_MinS32; 147bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 148bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 149bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Offset set the rectangle by adding dx to its left and right, 150bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com and adding dy to its top and bottom. 151bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 152bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void offset(int32_t dx, int32_t dy) { 153bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft += dx; 154bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop += dy; 155bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight += dx; 156bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom += dy; 157bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 158bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 159bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void offset(const SkIPoint& delta) { 160bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->offset(delta.fX, delta.fY); 161bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 162bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 163bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 164bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Offset this rect such its new x() and y() will equal newX and newY. 165bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 166bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void offsetTo(int32_t newX, int32_t newY) { 167bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight += newX - fLeft; 168bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom += newY - fTop; 169bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = newX; 170bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = newY; 171bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 172bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 173bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards, 174bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com making the rectangle narrower. If dx is negative, then the sides are moved outwards, 175bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com making the rectangle wider. The same holds true for dy and the top and bottom. 176bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 177bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void inset(int32_t dx, int32_t dy) { 178bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft += dx; 179bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop += dy; 180bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight -= dx; 181bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom -= dy; 182bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 183bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 184bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are 185bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com moved outwards, making the rectangle wider. If dx is negative, then the 186bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com sides are moved inwards, making the rectangle narrower. The same holds 187bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com true for dy and the top and bottom. 188bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 189bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void outset(int32_t dx, int32_t dy) { this->inset(-dx, -dy); } 190bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 191bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool quickReject(int l, int t, int r, int b) const { 192bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b; 193bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 194bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 195bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Returns true if (x,y) is inside the rectangle and the rectangle is not 196bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com empty. The left and top are considered to be inside, while the right 197bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com and bottom are not. Thus for the rectangle (0, 0, 5, 10), the 198bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not. 199bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 200bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool contains(int32_t x, int32_t y) const { 201bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) && 202bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (unsigned)(y - fTop) < (unsigned)(fBottom - fTop); 203bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 204bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 205bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle. 206bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If either rectangle is empty, contains() returns false. 207bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 208bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const { 209bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return left < right && top < bottom && !this->isEmpty() && // check for empties 210bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft <= left && fTop <= top && 211bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight >= right && fBottom >= bottom; 212bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 213bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 214bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Returns true if the specified rectangle r is inside or equal to this rectangle. 215bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 216bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool contains(const SkIRect& r) const { 217bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return !r.isEmpty() && !this->isEmpty() && // check for empties 218bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft <= r.fLeft && fTop <= r.fTop && 219bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight >= r.fRight && fBottom >= r.fBottom; 220bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 221bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 222bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Return true if this rectangle contains the specified rectangle. 223bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com For speed, this method does not check if either this or the specified 224bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rectangles are empty, and if either is, its return value is undefined. 225bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com In the debugging build however, we assert that both this and the 226bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com specified rectangles are non-empty. 227bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 228bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool containsNoEmptyCheck(int32_t left, int32_t top, 229bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int32_t right, int32_t bottom) const { 230bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(fLeft < fRight && fTop < fBottom); 231bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(left < right && top < bottom); 232bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 233bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return fLeft <= left && fTop <= top && 234bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight >= right && fBottom >= bottom; 235bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 236bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 237bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool containsNoEmptyCheck(const SkIRect& r) const { 238bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return containsNoEmptyCheck(r.fLeft, r.fTop, r.fRight, r.fBottom); 239bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 240bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 241bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** If r intersects this rectangle, return true and set this rectangle to that 242bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com intersection, otherwise return false and do not change this rectangle. 243bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If either rectangle is empty, do nothing and return false. 244bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 245bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool intersect(const SkIRect& r) { 246bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(&r); 247bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); 248bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 249bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 250bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** If rectangles a and b intersect, return true and set this rectangle to 251bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com that intersection, otherwise return false and do not change this 252bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rectangle. If either rectangle is empty, do nothing and return false. 253bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 254bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool intersect(const SkIRect& a, const SkIRect& b) { 255bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(&a && &b); 256bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 257bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (!a.isEmpty() && !b.isEmpty() && 258bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com a.fLeft < b.fRight && b.fLeft < a.fRight && 259bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom) { 260bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = SkMax32(a.fLeft, b.fLeft); 261bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = SkMax32(a.fTop, b.fTop); 262bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight = SkMin32(a.fRight, b.fRight); 263bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom = SkMin32(a.fBottom, b.fBottom); 264bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 265bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 266bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 267bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 268bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 269bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** If rectangles a and b intersect, return true and set this rectangle to 270bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com that intersection, otherwise return false and do not change this 271bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rectangle. For speed, no check to see if a or b are empty is performed. 272bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If either is, then the return result is undefined. In the debug build, 273bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com we assert that both rectangles are non-empty. 274bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 275bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) { 276bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(&a && &b); 277bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(!a.isEmpty() && !b.isEmpty()); 278bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 279bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (a.fLeft < b.fRight && b.fLeft < a.fRight && 280bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom) { 281bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = SkMax32(a.fLeft, b.fLeft); 282bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = SkMax32(a.fTop, b.fTop); 283bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight = SkMin32(a.fRight, b.fRight); 284bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom = SkMin32(a.fBottom, b.fBottom); 285bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 286bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 287bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 288bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 289bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 290bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** If the rectangle specified by left,top,right,bottom intersects this rectangle, 291bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true and set this rectangle to that intersection, 292bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com otherwise return false and do not change this rectangle. 293bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If either rectangle is empty, do nothing and return false. 294bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 295bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom) { 296bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (left < right && top < bottom && !this->isEmpty() && 297bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft < right && left < fRight && fTop < bottom && top < fBottom) { 298bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fLeft < left) fLeft = left; 299bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fTop < top) fTop = top; 300bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fRight > right) fRight = right; 301bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (fBottom > bottom) fBottom = bottom; 302bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true; 303bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 304bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return false; 305bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 306bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 307cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com /** Returns true if a and b are not empty, and they intersect 308cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com */ 309cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com static bool Intersects(const SkIRect& a, const SkIRect& b) { 310bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return !a.isEmpty() && !b.isEmpty() && // check for empties 311bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com a.fLeft < b.fRight && b.fLeft < a.fRight && 312bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom; 313bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 314bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 315bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 316b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com * Returns true if a and b intersect. debug-asserts that neither are empty. 317b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com */ 318b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b) { 319b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com SkASSERT(!a.isEmpty()); 320b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com SkASSERT(!b.isEmpty()); 321b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com return a.fLeft < b.fRight && b.fLeft < a.fRight && 322b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom; 323b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com } 324bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 325bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 326bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 327bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rectangle is empty, do nothing. 328bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 329bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void join(int32_t left, int32_t top, int32_t right, int32_t bottom); 330bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 331bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 332bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 333bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rectangle is empty, do nothing. 334b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com */ 335bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void join(const SkIRect& r) { 336bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); 337bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 338bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 339b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com /** Swap top/bottom or left/right if there are flipped. 340b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com This can be called if the edges are computed separately, 341b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com and may have crossed over each other. 342b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com When this returns, left <= right && top <= bottom 343b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com */ 344b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com void sort(); 345b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com 346b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com static const SkIRect& SK_WARN_UNUSED_RESULT EmptyIRect() { 347bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static const SkIRect gEmpty = { 0, 0, 0, 0 }; 348bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return gEmpty; 349bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 350b35fe4e1b04229a849227ea6c2561fe84929ab8breed@android.com}; 351bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 352bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com/** \struct SkRect 353bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com*/ 354bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstruct SK_API SkRect { 355bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar fLeft, fTop, fRight, fBottom; 356bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 357bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkRect SK_WARN_UNUSED_RESULT MakeEmpty() { 358bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRect r; 359bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.setEmpty(); 360bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 361bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 362bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 363bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h) { 364bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRect r; 365bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.set(0, 0, w, h); 366bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 367bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 368bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 369bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size) { 370bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRect r; 371bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.set(0, 0, size.width(), size.height()); 372bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 373bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 374bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 375bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) { 376bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRect rect; 377bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rect.set(l, t, r, b); 378e5dd6cd1e1addbc58df3d0f55655448140490002reed@android.com return rect; 379bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 380bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 381bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) { 382bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRect r; 383bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.set(x, y, x + w, y + h); 384bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 385bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 386bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 387bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static SkRect SK_WARN_UNUSED_RESULT MakeFromIRect(const SkIRect& irect) { 388bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkRect r; 389bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com r.set(SkIntToScalar(irect.fLeft), 390bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIntToScalar(irect.fTop), 391bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIntToScalar(irect.fRight), 392bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkIntToScalar(irect.fBottom)); 393bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return r; 394bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 395bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 396bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 397bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Return true if the rectangle's width or height are <= 0 398bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 399bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } 400bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 401bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 402bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Returns true iff all values in the rect are finite. If any are 403bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this 404bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * returns false. 405bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 406bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool isFinite() const { 407bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#ifdef SK_SCALAR_IS_FLOAT 408bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com float accum = 0; 409bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com accum *= fLeft; 410bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com accum *= fTop; 411bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com accum *= fRight; 412bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com accum *= fBottom; 413bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 414e5dd6cd1e1addbc58df3d0f55655448140490002reed@android.com // accum is either NaN or it is finite (zero). 415bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(0 == accum || !(accum == accum)); 416bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 417bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // value==value will be true iff value is not NaN 4186aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com // TODO: is it faster to say !accum or accum==accum? 419bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return accum == accum; 4206aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com#else 4216aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com // use bit-or for speed, since we don't care about short-circuting the 4226aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com // tests, and we expect the common case will be that we need to check all. 4236aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com int isNaN = (SK_FixedNaN == fLeft) | (SK_FixedNaN == fTop) | 4246aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com (SK_FixedNaN == fRight) | (SK_FixedNaN == fBottom); 4256aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com return !isNaN; 4266aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com#endif 4276aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com } 4286aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com 4296aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com SkScalar x() const { return fLeft; } 4306aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com SkScalar y() const { return fTop; } 4316aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com SkScalar left() const { return fLeft; } 4326aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com SkScalar top() const { return fTop; } 4336aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com SkScalar right() const { return fRight; } 4346aa3c7b33e224af3ac3c75797de40498bd3d645creed@android.com SkScalar bottom() const { return fBottom; } 435bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar width() const { return fRight - fLeft; } 436bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar height() const { return fBottom - fTop; } 437cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); } 438bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); } 439f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com 440f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com friend bool operator==(const SkRect& a, const SkRect& b) { 441f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com return SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4); 442f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com } 443f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com 444f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com friend bool operator!=(const SkRect& a, const SkRect& b) { 445f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com return !SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4); 446f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com } 447f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com 448f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com /** return the 4 points that enclose the rectangle 449f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com */ 450f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com void toQuad(SkPoint quad[4]) const; 451f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com 452f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com /** Set this rectangle to the empty rectangle (0,0,0,0) 453f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com */ 454f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com void setEmpty() { memset(this, 0, sizeof(*this)); } 455f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com 456f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com void set(const SkIRect& src) { 457f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com fLeft = SkIntToScalar(src.fLeft); 458f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com fTop = SkIntToScalar(src.fTop); 459f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com fRight = SkIntToScalar(src.fRight); 460f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com fBottom = SkIntToScalar(src.fBottom); 461f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com } 462f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com 463f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) { 464f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com fLeft = left; 465f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com fTop = top; 466f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com fRight = right; 467f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com fBottom = bottom; 468f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com } 469f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com // alias for set(l, t, r, b) 470f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com void setLTRB(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) { 471f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com this->set(left, top, right, bottom); 472f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com } 473f89965bebd372b993ee9949b60af9e6144c75bb7reed@android.com 474bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Initialize the rect with the 4 specified integers. The routine handles 475bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com converting them to scalars (by calling SkIntToScalar) 476bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 477bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void iset(int left, int top, int right, int bottom) { 478bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = SkIntToScalar(left); 479bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = SkIntToScalar(top); 480c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com fRight = SkIntToScalar(right); 481bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom = SkIntToScalar(bottom); 482bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 483bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 484cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com /** Set this rectangle to be the bounds of the array of points. 485cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com If the array is empty (count == 0), then set this rectangle 486cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com to the empty rectangle (0,0,0,0) 487cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com */ 488cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com void set(const SkPoint pts[], int count) { 489cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com // set() had been checking for non-finite values, so keep that behavior 490bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // for now. Now that we have setBoundsCheck(), we may decide to make 491bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // set() be simpler/faster, and not check for those. 492bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (void)this->setBoundsCheck(pts, count); 493bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 494bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 495bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // alias for set(pts, count) 496bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void setBounds(const SkPoint pts[], int count) { 497bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com (void)this->setBoundsCheck(pts, count); 498bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 499bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 500bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 501bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Compute the bounds of the array of points, and set this rect to that 502bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * bounds and return true... unless a non-finite value is encountered, 503bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * in which case this rect is set to empty and false is returned. 504cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com */ 505cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com bool setBoundsCheck(const SkPoint pts[], int count); 506cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com 507bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void set(const SkPoint& p0, const SkPoint& p1) { 508cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com fLeft = SkMinScalar(p0.fX, p1.fX); 509cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com fRight = SkMaxScalar(p0.fX, p1.fX); 510b44d151b082d859c467808a843dc01a7118ce5cfreed@android.com fTop = SkMinScalar(p0.fY, p1.fY); 5117d27207b0d54e59a7b5722247322fbf4344d44a1agl@chromium.org fBottom = SkMaxScalar(p0.fY, p1.fY); 5127d27207b0d54e59a7b5722247322fbf4344d44a1agl@chromium.org } 5137d27207b0d54e59a7b5722247322fbf4344d44a1agl@chromium.org 5147d27207b0d54e59a7b5722247322fbf4344d44a1agl@chromium.org void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) { 5157d27207b0d54e59a7b5722247322fbf4344d44a1agl@chromium.org fLeft = x; 5167d27207b0d54e59a7b5722247322fbf4344d44a1agl@chromium.org fTop = y; 5177d27207b0d54e59a7b5722247322fbf4344d44a1agl@chromium.org fRight = x + width; 5187d27207b0d54e59a7b5722247322fbf4344d44a1agl@chromium.org fBottom = y + height; 519bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 520bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 521bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void setWH(SkScalar width, SkScalar height) { 522cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com fLeft = 0; 523bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = 0; 524cfaf6fa015476b3283441e11a74c488aa8d700e6reed@android.com fRight = width; 525bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom = height; 526bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 527bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 528bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 529bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Make the largest representable rectangle 530bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 531bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void setLargest() { 532bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = fTop = SK_ScalarMin; 533bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight = fBottom = SK_ScalarMax; 534bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 535bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 536bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 537bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Make the largest representable rectangle, but inverted (e.g. fLeft will 538bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * be max and right will be min). 539c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com */ 540bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void setLargestInverted() { 541c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com fLeft = fTop = SK_ScalarMax; 542c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com fRight = fBottom = SK_ScalarMin; 543c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com } 544bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 545bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Offset set the rectangle by adding dx to its left and right, 546bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com and adding dy to its top and bottom. 547bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 548bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void offset(SkScalar dx, SkScalar dy) { 549bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft += dx; 550bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop += dy; 551bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight += dx; 552bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom += dy; 553bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 554bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 555bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void offset(const SkPoint& delta) { 556bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->offset(delta.fX, delta.fY); 557c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com } 558bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 559bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 560bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Offset this rect such its new x() and y() will equal newX and newY. 561bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 562bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void offsetTo(SkScalar newX, SkScalar newY) { 563bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight += newX - fLeft; 564bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom += newY - fTop; 565bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = newX; 566bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = newY; 567bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 568bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 569bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are 570bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com moved inwards, making the rectangle narrower. If dx is negative, then 571bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com the sides are moved outwards, making the rectangle wider. The same holds 572bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com true for dy and the top and bottom. 573bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 574bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void inset(SkScalar dx, SkScalar dy) { 575bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft += dx; 576bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop += dy; 577bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight -= dx; 578bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom -= dy; 579bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 580bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 581bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are 582bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com moved outwards, making the rectangle wider. If dx is negative, then the 583bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com sides are moved inwards, making the rectangle narrower. The same holds 584bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com true for dy and the top and bottom. 585bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 586bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void outset(SkScalar dx, SkScalar dy) { this->inset(-dx, -dy); } 587bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 588bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** If this rectangle intersects r, return true and set this rectangle to that 589bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com intersection, otherwise return false and do not change this rectangle. 590bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If either rectangle is empty, do nothing and return false. 591bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 592bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool intersect(const SkRect& r); 593bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 594bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** If this rectangle intersects the rectangle specified by left, top, right, bottom, 595bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return true and set this rectangle to that intersection, otherwise return false 596bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com and do not change this rectangle. 597bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If either rectangle is empty, do nothing and return false. 598bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 599bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); 600bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 601bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 602bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Return true if this rectangle is not empty, and the specified sides of 603bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * a rectangle are not empty, and they intersect. 604bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 605bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const { 606bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return // first check that both are not empty 607bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com left < right && top < bottom && 608bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft < fRight && fTop < fBottom && 609bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // now check for intersection 610bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft < right && left < fRight && 611bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop < bottom && top < fBottom; 612bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 613bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 614bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** If rectangles a and b intersect, return true and set this rectangle to 615bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * that intersection, otherwise return false and do not change this 616bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * rectangle. If either rectangle is empty, do nothing and return false. 617bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 618bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool intersect(const SkRect& a, const SkRect& b); 619bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 620bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 621bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Return true if rectangles a and b are not empty and intersect. 622bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 623bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com static bool Intersects(const SkRect& a, const SkRect& b) { 624bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return !a.isEmpty() && !b.isEmpty() && 625bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com a.fLeft < b.fRight && b.fLeft < a.fRight && 626155c4e804736576f9352aa60d70669ac3e3f9d52reed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom; 627bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 628bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 629bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 630bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Update this rectangle to enclose itself and the specified rectangle. 631bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * If this rectangle is empty, just set it to the specified rectangle. 632bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * If the specified rectangle is empty, do nothing. 633bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 634bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); 635bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 636bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 637bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 638bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com rectangle is empty, do nothing. 639bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 640bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void join(const SkRect& r) { 641c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); 642bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 643bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // alias for join() 644bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void growToInclude(const SkRect& r) { this->join(r); } 645bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 646bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 647bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Grow the rect to include the specified (x,y). After this call, the 648bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * following will be true: fLeft <= x <= fRight && fTop <= y <= fBottom. 649bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * 650bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * This is close, but not quite the same contract as contains(), since 651bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * contains() treats the left and top different from the right and bottom. 652bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * contains(x,y) -> fLeft <= x < fRight && fTop <= y < fBottom. Also note 653bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * that contains(x,y) always returns false if the rect is empty. 654bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 655bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void growToInclude(SkScalar x, SkScalar y) { 656bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft = SkMinScalar(x, fLeft); 657bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight = SkMaxScalar(x, fRight); 658bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fTop = SkMinScalar(y, fTop); 659bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fBottom = SkMaxScalar(y, fBottom); 660bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 661bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 662bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 663bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Returns true if (p.fX,p.fY) is inside the rectangle, and the rectangle 664bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * is not empty. 665bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * 666bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Contains treats the left and top differently from the right and bottom. 667bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * The left and top coordinates of the rectangle are themselves considered 6682258a80c91fa183971ea3ed987c528e835fe9481reed@android.com * to be inside, while the right and bottom are not. Thus for the rectangle 6692258a80c91fa183971ea3ed987c528e835fe9481reed@android.com * {0, 0, 5, 10}, (0,0) is contained, but (0,10), (5,0) and (5,10) are not. 670bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 671bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool contains(const SkPoint& p) const { 672bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return !this->isEmpty() && 673bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft <= p.fX && p.fX < fRight && fTop <= p.fY && p.fY < fBottom; 674bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 675bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 676bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 677bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Returns true if (x,y) is inside the rectangle, and the rectangle 678bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * is not empty. 679bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * 680bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Contains treats the left and top differently from the right and bottom. 681bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * The left and top coordinates of the rectangle are themselves considered 682bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * to be inside, while the right and bottom are not. Thus for the rectangle 683bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * {0, 0, 5, 10}, (0,0) is contained, but (0,10), (5,0) and (5,10) are not. 684bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 685bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool contains(SkScalar x, SkScalar y) const { 686bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return !this->isEmpty() && 687bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft <= x && x < fRight && fTop <= y && y < fBottom; 688bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 689bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 690bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 691bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Return true if this rectangle contains r, and if both rectangles are 692bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * not empty. 693bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 694bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com bool contains(const SkRect& r) const { 695bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return !r.isEmpty() && !this->isEmpty() && 696bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fLeft <= r.fLeft && fTop <= r.fTop && 697bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fRight >= r.fRight && fBottom >= r.fBottom; 698bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 699bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 700bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 701c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com * Set the dst rectangle by rounding this rectangle's coordinates to their 702c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com * nearest integer values using SkScalarRound. 703c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com */ 704c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com void round(SkIRect* dst) const { 705c5f637cf3cecf921d7899c60181447a41ef5f10creed@android.com SkASSERT(dst); 706bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com dst->set(SkScalarRoundToInt(fLeft), SkScalarRoundToInt(fTop), 707bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalarRoundToInt(fRight), SkScalarRoundToInt(fBottom)); 708bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 709bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 710bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 711bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Set the dst rectangle by rounding "out" this rectangle, choosing the 712bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * SkScalarFloor of top and left, and the SkScalarCeil of right and bottom. 713bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 714bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void roundOut(SkIRect* dst) const { 715bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(dst); 716bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com dst->set(SkScalarFloorToInt(fLeft), SkScalarFloorToInt(fTop), 717bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalarCeilToInt(fRight), SkScalarCeilToInt(fBottom)); 718bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 719bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 720bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com /** 721bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * Expand this rectangle by rounding its coordinates "out", choosing the 722bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * floor of top and left, and the ceil of right and bottom. If this rect 723bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com * is already on integer coordinates, then it will be unchanged. 724bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com */ 725bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com void roundOut() { 726bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com this->set(SkScalarFloorToScalar(fLeft), 727bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalarFloorToScalar(fTop), 728bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalarCeilToScalar(fRight), 729bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkScalarCeilToScalar(fBottom)); 730 } 731 732 /** 733 * Set the dst rectangle by rounding "in" this rectangle, choosing the 734 * ceil of top and left, and the floor of right and bottom. This does *not* 735 * call sort(), so it is possible that the resulting rect is inverted... 736 * e.g. left >= right or top >= bottom. Call isEmpty() to detect that. 737 */ 738 void roundIn(SkIRect* dst) const { 739 SkASSERT(dst); 740 dst->set(SkScalarCeilToInt(fLeft), SkScalarCeilToInt(fTop), 741 SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom)); 742 } 743 744 745 /** 746 * Swap top/bottom or left/right if there are flipped (i.e. if width() 747 * or height() would have returned a negative value.) This should be called 748 * if the edges are computed separately, and may have crossed over each 749 * other. When this returns, left <= right && top <= bottom 750 */ 751 void sort(); 752}; 753 754#endif 755 756