1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkRect_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkRect_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPoint.h" 14233481ebd0b8644a319443cde33e75266e990ee6reed@android.com#include "SkSize.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \struct SkIRect 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect holds four 32 bit integer coordinates for a rectangle 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 207ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgstruct SK_API SkIRect { 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t fLeft, fTop, fRight, fBottom; 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 235d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkIRect SK_WARN_UNUSED_RESULT MakeEmpty() { 24097a3513535ad854c1b049c32c080ec875ab1411reed@android.com SkIRect r; 25097a3513535ad854c1b049c32c080ec875ab1411reed@android.com r.setEmpty(); 26097a3513535ad854c1b049c32c080ec875ab1411reed@android.com return r; 27097a3513535ad854c1b049c32c080ec875ab1411reed@android.com } 28fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 29194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org static SkIRect SK_WARN_UNUSED_RESULT MakeLargest() { 30194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SkIRect r; 31194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org r.setLargest(); 32194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org return r; 33194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org } 34194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 355d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h) { 36097a3513535ad854c1b049c32c080ec875ab1411reed@android.com SkIRect r; 37097a3513535ad854c1b049c32c080ec875ab1411reed@android.com r.set(0, 0, w, h); 38097a3513535ad854c1b049c32c080ec875ab1411reed@android.com return r; 39097a3513535ad854c1b049c32c080ec875ab1411reed@android.com } 40fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 415d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size) { 42097a3513535ad854c1b049c32c080ec875ab1411reed@android.com SkIRect r; 43097a3513535ad854c1b049c32c080ec875ab1411reed@android.com r.set(0, 0, size.width(), size.height()); 44097a3513535ad854c1b049c32c080ec875ab1411reed@android.com return r; 45097a3513535ad854c1b049c32c080ec875ab1411reed@android.com } 46fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 475d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) { 48097a3513535ad854c1b049c32c080ec875ab1411reed@android.com SkIRect rect; 49097a3513535ad854c1b049c32c080ec875ab1411reed@android.com rect.set(l, t, r, b); 50097a3513535ad854c1b049c32c080ec875ab1411reed@android.com return rect; 51097a3513535ad854c1b049c32c080ec875ab1411reed@android.com } 52fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 535d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) { 54097a3513535ad854c1b049c32c080ec875ab1411reed@android.com SkIRect r; 55097a3513535ad854c1b049c32c080ec875ab1411reed@android.com r.set(x, y, x + w, y + h); 56097a3513535ad854c1b049c32c080ec875ab1411reed@android.com return r; 57097a3513535ad854c1b049c32c080ec875ab1411reed@android.com } 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 59c74ab1813013b169ad500fcf1fa62be551041442reed@google.com int left() const { return fLeft; } 60c74ab1813013b169ad500fcf1fa62be551041442reed@google.com int top() const { return fTop; } 61c74ab1813013b169ad500fcf1fa62be551041442reed@google.com int right() const { return fRight; } 62c74ab1813013b169ad500fcf1fa62be551041442reed@google.com int bottom() const { return fBottom; } 63fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 64c74ab1813013b169ad500fcf1fa62be551041442reed@google.com /** return the left edge of the rect */ 65c74ab1813013b169ad500fcf1fa62be551041442reed@google.com int x() const { return fLeft; } 66c74ab1813013b169ad500fcf1fa62be551041442reed@google.com /** return the top edge of the rect */ 67c74ab1813013b169ad500fcf1fa62be551041442reed@google.com int y() const { return fTop; } 68c74ab1813013b169ad500fcf1fa62be551041442reed@google.com /** 69c74ab1813013b169ad500fcf1fa62be551041442reed@google.com * Returns the rectangle's width. This does not check for a valid rect 70c74ab1813013b169ad500fcf1fa62be551041442reed@google.com * (i.e. left <= right) so the result may be negative. 71c74ab1813013b169ad500fcf1fa62be551041442reed@google.com */ 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int width() const { return fRight - fLeft; } 73fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 74c74ab1813013b169ad500fcf1fa62be551041442reed@google.com /** 75c74ab1813013b169ad500fcf1fa62be551041442reed@google.com * Returns the rectangle's height. This does not check for a valid rect 76c74ab1813013b169ad500fcf1fa62be551041442reed@google.com * (i.e. top <= bottom) so the result may be negative. 77c74ab1813013b169ad500fcf1fa62be551041442reed@google.com */ 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int height() const { return fBottom - fTop; } 79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 80c74ab1813013b169ad500fcf1fa62be551041442reed@google.com /** 816898d52c371309d81c2184ea991785d2485323e4reed@google.com * Since the center of an integer rect may fall on a factional value, this 826898d52c371309d81c2184ea991785d2485323e4reed@google.com * method is defined to return (right + left) >> 1. 836898d52c371309d81c2184ea991785d2485323e4reed@google.com * 846898d52c371309d81c2184ea991785d2485323e4reed@google.com * This is a specific "truncation" of the average, which is different than 856898d52c371309d81c2184ea991785d2485323e4reed@google.com * (right + left) / 2 when the sum is negative. 866898d52c371309d81c2184ea991785d2485323e4reed@google.com */ 876898d52c371309d81c2184ea991785d2485323e4reed@google.com int centerX() const { return (fRight + fLeft) >> 1; } 88d9f7503e0cb0c4db856f53b4bdeec1332db6f296skia.committer@gmail.com 896898d52c371309d81c2184ea991785d2485323e4reed@google.com /** 906898d52c371309d81c2184ea991785d2485323e4reed@google.com * Since the center of an integer rect may fall on a factional value, this 916898d52c371309d81c2184ea991785d2485323e4reed@google.com * method is defined to return (bottom + top) >> 1 926898d52c371309d81c2184ea991785d2485323e4reed@google.com * 936898d52c371309d81c2184ea991785d2485323e4reed@google.com * This is a specific "truncation" of the average, which is different than 946898d52c371309d81c2184ea991785d2485323e4reed@google.com * (bottom + top) / 2 when the sum is negative. 956898d52c371309d81c2184ea991785d2485323e4reed@google.com */ 966898d52c371309d81c2184ea991785d2485323e4reed@google.com int centerY() const { return (fBottom + fTop) >> 1; } 97d9f7503e0cb0c4db856f53b4bdeec1332db6f296skia.committer@gmail.com 986898d52c371309d81c2184ea991785d2485323e4reed@google.com /** 99c74ab1813013b169ad500fcf1fa62be551041442reed@google.com * Return true if the rectangle's width or height are <= 0 100c74ab1813013b169ad500fcf1fa62be551041442reed@google.com */ 101c74ab1813013b169ad500fcf1fa62be551041442reed@google.com bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } 102fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 103194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org bool isLargest() const { return SK_MinS32 == fLeft && 104194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SK_MinS32 == fTop && 105194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SK_MaxS32 == fRight && 106194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SK_MaxS32 == fBottom; } 107194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 108b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com friend bool operator==(const SkIRect& a, const SkIRect& b) { 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return !memcmp(&a, &b, sizeof(a)); 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 111da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 112b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com friend bool operator!=(const SkIRect& a, const SkIRect& b) { 113b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com return !(a == b); 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 116d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com bool is16Bit() const { 117d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com return SkIsS16(fLeft) && SkIsS16(fTop) && 118d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com SkIsS16(fRight) && SkIsS16(fBottom); 119d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com } 120d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the rectangle to (0,0,0,0) 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setEmpty() { memset(this, 0, sizeof(*this)); } 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 125da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void set(int32_t left, int32_t top, int32_t right, int32_t bottom) { 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = left; 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = top; 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = right; 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = bottom; 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com // alias for set(l, t, r, b) 13220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) { 13320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com this->set(left, top, right, bottom); 13420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1361d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) { 1371d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fLeft = x; 1381d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fTop = y; 1391d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fRight = x + width; 1401d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fBottom = y + height; 1411d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com } 14220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 14320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com /** 14420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Make the largest representable rectangle 14520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 14620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLargest() { 14720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = fTop = SK_MinS32; 14820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fRight = fBottom = SK_MaxS32; 14920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 150fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 15120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com /** 15220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Make the largest representable rectangle, but inverted (e.g. fLeft will 15320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * be max 32bit and right will be min 32bit). 15420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 15520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLargestInverted() { 15620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = fTop = SK_MaxS32; 15720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fRight = fBottom = SK_MinS32; 15820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 159fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1605c404c55772973126d8b3c6942ee42c9361d3fadreed /** 1615c404c55772973126d8b3c6942ee42c9361d3fadreed * Return a new IRect, built as an offset of this rect. 1625c404c55772973126d8b3c6942ee42c9361d3fadreed */ 1635c404c55772973126d8b3c6942ee42c9361d3fadreed SkIRect makeOffset(int dx, int dy) const { 1645c404c55772973126d8b3c6942ee42c9361d3fadreed return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); 1655c404c55772973126d8b3c6942ee42c9361d3fadreed } 1665c404c55772973126d8b3c6942ee42c9361d3fadreed 1675c404c55772973126d8b3c6942ee42c9361d3fadreed /** 1685c404c55772973126d8b3c6942ee42c9361d3fadreed * Return a new IRect, built as an inset of this rect. 1695c404c55772973126d8b3c6942ee42c9361d3fadreed */ 1705c404c55772973126d8b3c6942ee42c9361d3fadreed SkIRect makeInset(int dx, int dy) const { 1715c404c55772973126d8b3c6942ee42c9361d3fadreed return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); 1725c404c55772973126d8b3c6942ee42c9361d3fadreed } 1735c404c55772973126d8b3c6942ee42c9361d3fadreed 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Offset set the rectangle by adding dx to its left and right, 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and adding dy to its top and bottom. 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 177da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void offset(int32_t dx, int32_t dy) { 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft += dx; 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop += dy; 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight += dx; 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom += dy; 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 184da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void offset(const SkIPoint& delta) { 185da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com this->offset(delta.fX, delta.fY); 186da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com } 187da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 1884d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com /** 1894d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * Offset this rect such its new x() and y() will equal newX and newY. 1904d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com */ 1914d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com void offsetTo(int32_t newX, int32_t newY) { 1924d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fRight += newX - fLeft; 1934d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fBottom += newY - fTop; 1944d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fLeft = newX; 1954d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fTop = newY; 1964d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com } 1974d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards, 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com making the rectangle narrower. If dx is negative, then the sides are moved outwards, 2006623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com making the rectangle wider. The same holds true for dy and the top and bottom. 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 202da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void inset(int32_t dx, int32_t dy) { 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft += dx; 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop += dy; 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight -= dx; 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom -= dy; 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 208da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 2096623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are 2106623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com moved outwards, making the rectangle wider. If dx is negative, then the 2116623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com sides are moved inwards, making the rectangle narrower. The same holds 2126623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com true for dy and the top and bottom. 2136623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com */ 2146623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com void outset(int32_t dx, int32_t dy) { this->inset(-dx, -dy); } 2156623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com 21620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com bool quickReject(int l, int t, int r, int b) const { 21720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b; 21820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 219fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if (x,y) is inside the rectangle and the rectangle is not 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com empty. The left and top are considered to be inside, while the right 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and bottom are not. Thus for the rectangle (0, 0, 5, 10), the 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not. 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 225da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool contains(int32_t x, int32_t y) const { 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) && 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (unsigned)(y - fTop) < (unsigned)(fBottom - fTop); 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle. 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, contains() returns false. 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 233da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const { 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return left < right && top < bottom && !this->isEmpty() && // check for empties 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft <= left && fTop <= top && 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight >= right && fBottom >= bottom; 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the specified rectangle r is inside or equal to this rectangle. 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 241da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool contains(const SkIRect& r) const { 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return !r.isEmpty() && !this->isEmpty() && // check for empties 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft <= r.fLeft && fTop <= r.fTop && 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight >= r.fRight && fBottom >= r.fBottom; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return true if this rectangle contains the specified rectangle. 2485d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com For speed, this method does not check if either this or the specified 2495d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com rectangles are empty, and if either is, its return value is undefined. 2505d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com In the debugging build however, we assert that both this and the 2515d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com specified rectangles are non-empty. 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool containsNoEmptyCheck(int32_t left, int32_t top, 2545d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com int32_t right, int32_t bottom) const { 2555d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com SkASSERT(fLeft < fRight && fTop < fBottom); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(left < right && top < bottom); 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fLeft <= left && fTop <= top && 2595d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com fRight >= right && fBottom >= bottom; 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 261fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2620d10280190c411b18feb569a2248552047d1aa93reed@google.com bool containsNoEmptyCheck(const SkIRect& r) const { 2630d10280190c411b18feb569a2248552047d1aa93reed@google.com return containsNoEmptyCheck(r.fLeft, r.fTop, r.fRight, r.fBottom); 2640d10280190c411b18feb569a2248552047d1aa93reed@google.com } 265fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If r intersects this rectangle, return true and set this rectangle to that 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com intersection, otherwise return false and do not change this rectangle. 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, do nothing and return false. 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 270da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool intersect(const SkIRect& r) { 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(&r); 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If rectangles a and b intersect, return true and set this rectangle to 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com that intersection, otherwise return false and do not change this 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle. If either rectangle is empty, do nothing and return false. 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 279da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool intersect(const SkIRect& a, const SkIRect& b) { 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(&a && &b); 281fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!a.isEmpty() && !b.isEmpty() && 283da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com a.fLeft < b.fRight && b.fLeft < a.fRight && 284da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom) { 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = SkMax32(a.fLeft, b.fLeft); 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = SkMax32(a.fTop, b.fTop); 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = SkMin32(a.fRight, b.fRight); 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = SkMin32(a.fBottom, b.fBottom); 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 293fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If rectangles a and b intersect, return true and set this rectangle to 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com that intersection, otherwise return false and do not change this 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle. For speed, no check to see if a or b are empty is performed. 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either is, then the return result is undefined. In the debug build, 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com we assert that both rectangles are non-empty. 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 300da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) { 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(&a && &b); 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!a.isEmpty() && !b.isEmpty()); 303fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (a.fLeft < b.fRight && b.fLeft < a.fRight && 305da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom) { 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = SkMax32(a.fLeft, b.fLeft); 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = SkMax32(a.fTop, b.fTop); 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = SkMin32(a.fRight, b.fRight); 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = SkMin32(a.fBottom, b.fBottom); 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If the rectangle specified by left,top,right,bottom intersects this rectangle, 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true and set this rectangle to that intersection, 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com otherwise return false and do not change this rectangle. 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, do nothing and return false. 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 320da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom) { 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (left < right && top < bottom && !this->isEmpty() && 322da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com fLeft < right && left < fRight && fTop < bottom && top < fBottom) { 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLeft < left) fLeft = left; 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fTop < top) fTop = top; 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fRight > right) fRight = right; 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fBottom > bottom) fBottom = bottom; 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 331fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if a and b are not empty, and they intersect 3330d10280190c411b18feb569a2248552047d1aa93reed@google.com */ 334da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com static bool Intersects(const SkIRect& a, const SkIRect& b) { 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return !a.isEmpty() && !b.isEmpty() && // check for empties 3360d10280190c411b18feb569a2248552047d1aa93reed@google.com a.fLeft < b.fRight && b.fLeft < a.fRight && 3370d10280190c411b18feb569a2248552047d1aa93reed@google.com a.fTop < b.fBottom && b.fTop < a.fBottom; 3380d10280190c411b18feb569a2248552047d1aa93reed@google.com } 339fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3400d10280190c411b18feb569a2248552047d1aa93reed@google.com /** 3410d10280190c411b18feb569a2248552047d1aa93reed@google.com * Returns true if a and b intersect. debug-asserts that neither are empty. 3420d10280190c411b18feb569a2248552047d1aa93reed@google.com */ 3430d10280190c411b18feb569a2248552047d1aa93reed@google.com static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b) { 3440d10280190c411b18feb569a2248552047d1aa93reed@google.com SkASSERT(!a.isEmpty()); 3450d10280190c411b18feb569a2248552047d1aa93reed@google.com SkASSERT(!b.isEmpty()); 3460d10280190c411b18feb569a2248552047d1aa93reed@google.com return a.fLeft < b.fRight && b.fLeft < a.fRight && 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom; 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 349fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle is empty, do nothing. 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void join(int32_t left, int32_t top, int32_t right, int32_t bottom); 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle is empty, do nothing. 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 360da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void join(const SkIRect& r) { 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Swap top/bottom or left/right if there are flipped. 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This can be called if the edges are computed separately, 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and may have crossed over each other. 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com When this returns, left <= right && top <= bottom 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void sort(); 37020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 3715d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static const SkIRect& SK_WARN_UNUSED_RESULT EmptyIRect() { 3724b4fb3a52c32cd4937d51d1315624545973b1322reed@google.com static const SkIRect gEmpty = { 0, 0, 0, 0 }; 37320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return gEmpty; 37420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \struct SkRect 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 3797ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgstruct SK_API SkRect { 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar fLeft, fTop, fRight, fBottom; 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3825d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeEmpty() { 3832687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com SkRect r; 3842687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com r.setEmpty(); 3852687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com return r; 3862687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com } 3872687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com 388b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org static SkRect SK_WARN_UNUSED_RESULT MakeLargest() { 389b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SkRect r; 390b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org r.setLargest(); 391b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org return r; 392b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org } 393b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org 3945d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h) { 3952687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com SkRect r; 3962687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com r.set(0, 0, w, h); 3972687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com return r; 3982687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com } 3992687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com 4005d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size) { 401233481ebd0b8644a319443cde33e75266e990ee6reed@android.com SkRect r; 402233481ebd0b8644a319443cde33e75266e990ee6reed@android.com r.set(0, 0, size.width(), size.height()); 403233481ebd0b8644a319443cde33e75266e990ee6reed@android.com return r; 404233481ebd0b8644a319443cde33e75266e990ee6reed@android.com } 4054d28d9889b033777afc1950474296d37887ef71bskia.committer@gmail.com 4065d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) { 407233481ebd0b8644a319443cde33e75266e990ee6reed@android.com SkRect rect; 408233481ebd0b8644a319443cde33e75266e990ee6reed@android.com rect.set(l, t, r, b); 409233481ebd0b8644a319443cde33e75266e990ee6reed@android.com return rect; 410233481ebd0b8644a319443cde33e75266e990ee6reed@android.com } 411233481ebd0b8644a319443cde33e75266e990ee6reed@android.com 4125d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) { 413233481ebd0b8644a319443cde33e75266e990ee6reed@android.com SkRect r; 414233481ebd0b8644a319443cde33e75266e990ee6reed@android.com r.set(x, y, x + w, y + h); 4157b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com return r; 4167b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com } 4177b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com 4184469938e92d779dff05e745559e67907bbf21e78reed@google.com SK_ATTR_DEPRECATED("use Make()") 4197b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com static SkRect SK_WARN_UNUSED_RESULT MakeFromIRect(const SkIRect& irect) { 4207b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com SkRect r; 4217b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com r.set(SkIntToScalar(irect.fLeft), 4227b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com SkIntToScalar(irect.fTop), 4237b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com SkIntToScalar(irect.fRight), 4247b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com SkIntToScalar(irect.fBottom)); 425233481ebd0b8644a319443cde33e75266e990ee6reed@android.com return r; 426233481ebd0b8644a319443cde33e75266e990ee6reed@android.com } 42743a6b6a046774576378dfb725e19632a0c8530b7skia.committer@gmail.com 4281d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com static SkRect SK_WARN_UNUSED_RESULT Make(const SkIRect& irect) { 4291d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com SkRect r; 4301d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com r.set(SkIntToScalar(irect.fLeft), 4311d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com SkIntToScalar(irect.fTop), 4321d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com SkIntToScalar(irect.fRight), 4331d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com SkIntToScalar(irect.fBottom)); 4341d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com return r; 4351d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com } 43643a6b6a046774576378dfb725e19632a0c8530b7skia.committer@gmail.com 4371607863b608b7db6c813228768ed5d72997bbc82reed@google.com /** 4381607863b608b7db6c813228768ed5d72997bbc82reed@google.com * Return true if the rectangle's width or height are <= 0 4391607863b608b7db6c813228768ed5d72997bbc82reed@google.com */ 4401607863b608b7db6c813228768ed5d72997bbc82reed@google.com bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } 441fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 442b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org bool isLargest() const { return SK_ScalarMin == fLeft && 443b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SK_ScalarMin == fTop && 444b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SK_ScalarMax == fRight && 445b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SK_ScalarMax == fBottom; } 446b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org 4471607863b608b7db6c813228768ed5d72997bbc82reed@google.com /** 4481607863b608b7db6c813228768ed5d72997bbc82reed@google.com * Returns true iff all values in the rect are finite. If any are 4491607863b608b7db6c813228768ed5d72997bbc82reed@google.com * infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this 4501607863b608b7db6c813228768ed5d72997bbc82reed@google.com * returns false. 4511607863b608b7db6c813228768ed5d72997bbc82reed@google.com */ 4521607863b608b7db6c813228768ed5d72997bbc82reed@google.com bool isFinite() const { 4537b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com float accum = 0; 4547b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com accum *= fLeft; 4557b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com accum *= fTop; 4567b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com accum *= fRight; 4577b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com accum *= fBottom; 458fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4597b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com // accum is either NaN or it is finite (zero). 4607b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com SkASSERT(0 == accum || !(accum == accum)); 4617b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com 4621607863b608b7db6c813228768ed5d72997bbc82reed@google.com // value==value will be true iff value is not NaN 4637b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com // TODO: is it faster to say !accum or accum==accum? 4647b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com return accum == accum; 4651607863b608b7db6c813228768ed5d72997bbc82reed@google.com } 4661607863b608b7db6c813228768ed5d72997bbc82reed@google.com 467d6195f956fdccef865224520a624e3fd968573d0reed@google.com SkScalar x() const { return fLeft; } 468d6195f956fdccef865224520a624e3fd968573d0reed@google.com SkScalar y() const { return fTop; } 46920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com SkScalar left() const { return fLeft; } 47020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com SkScalar top() const { return fTop; } 47120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com SkScalar right() const { return fRight; } 47220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com SkScalar bottom() const { return fBottom; } 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar width() const { return fRight - fLeft; } 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar height() const { return fBottom - fTop; } 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); } 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); } 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478e174ea4bb1f07c4d15c50716012e5c8429e9afebbsalomon@google.com friend bool operator==(const SkRect& a, const SkRect& b) { 479e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com return SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4); 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 481da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 482e174ea4bb1f07c4d15c50716012e5c8429e9afebbsalomon@google.com friend bool operator!=(const SkRect& a, const SkRect& b) { 483e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com return !SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4); 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 48624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org /** return the 4 points that enclose the rectangle (top-left, top-right, bottom-right, 48724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org bottom-left). TODO: Consider adding param to control whether quad is CW or CCW. 48824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org */ 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void toQuad(SkPoint quad[4]) const; 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set this rectangle to the empty rectangle (0,0,0,0) 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setEmpty() { memset(this, 0, sizeof(*this)); } 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 495da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void set(const SkIRect& src) { 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = SkIntToScalar(src.fLeft); 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = SkIntToScalar(src.fTop); 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = SkIntToScalar(src.fRight); 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = SkIntToScalar(src.fBottom); 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 502da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) { 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = left; 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = top; 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = right; 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = bottom; 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 50820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com // alias for set(l, t, r, b) 50920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLTRB(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) { 51020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com this->set(left, top, right, bottom); 51120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 51220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Initialize the rect with the 4 specified integers. The routine handles 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com converting them to scalars (by calling SkIntToScalar) 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void iset(int left, int top, int right, int bottom) { 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = SkIntToScalar(left); 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = SkIntToScalar(top); 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = SkIntToScalar(right); 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = SkIntToScalar(bottom); 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5236f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com /** 5246f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com * Set this rectangle to be left/top at 0,0, and have the specified width 5256f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com * and height (automatically converted to SkScalar). 5266f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com */ 5276f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com void isetWH(int width, int height) { 5286f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com fLeft = fTop = 0; 5296f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com fRight = SkIntToScalar(width); 5306f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com fBottom = SkIntToScalar(height); 5316f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com } 5324d28d9889b033777afc1950474296d37887ef71bskia.committer@gmail.com 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set this rectangle to be the bounds of the array of points. 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If the array is empty (count == 0), then set this rectangle 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to the empty rectangle (0,0,0,0) 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 5370bb18bb264b26afca45452910437c09445e23a3creed@google.com void set(const SkPoint pts[], int count) { 5380bb18bb264b26afca45452910437c09445e23a3creed@google.com // set() had been checking for non-finite values, so keep that behavior 5390bb18bb264b26afca45452910437c09445e23a3creed@google.com // for now. Now that we have setBoundsCheck(), we may decide to make 5400bb18bb264b26afca45452910437c09445e23a3creed@google.com // set() be simpler/faster, and not check for those. 5410bb18bb264b26afca45452910437c09445e23a3creed@google.com (void)this->setBoundsCheck(pts, count); 5420bb18bb264b26afca45452910437c09445e23a3creed@google.com } 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com // alias for set(pts, count) 54520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setBounds(const SkPoint pts[], int count) { 5460bb18bb264b26afca45452910437c09445e23a3creed@google.com (void)this->setBoundsCheck(pts, count); 54720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 548fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 5490bb18bb264b26afca45452910437c09445e23a3creed@google.com /** 5500bb18bb264b26afca45452910437c09445e23a3creed@google.com * Compute the bounds of the array of points, and set this rect to that 5510bb18bb264b26afca45452910437c09445e23a3creed@google.com * bounds and return true... unless a non-finite value is encountered, 5520bb18bb264b26afca45452910437c09445e23a3creed@google.com * in which case this rect is set to empty and false is returned. 5530bb18bb264b26afca45452910437c09445e23a3creed@google.com */ 5540bb18bb264b26afca45452910437c09445e23a3creed@google.com bool setBoundsCheck(const SkPoint pts[], int count); 555fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 5567b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com void set(const SkPoint& p0, const SkPoint& p1) { 5577b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com fLeft = SkMinScalar(p0.fX, p1.fX); 5587b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com fRight = SkMaxScalar(p0.fX, p1.fX); 5597b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com fTop = SkMinScalar(p0.fY, p1.fY); 5607b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com fBottom = SkMaxScalar(p0.fY, p1.fY); 5617b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com } 5627b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com 5631d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) { 5641d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fLeft = x; 5651d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fTop = y; 5661d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fRight = x + width; 5671d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fBottom = y + height; 5681d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com } 5691d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com 5703ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com void setWH(SkScalar width, SkScalar height) { 5713ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com fLeft = 0; 5723ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com fTop = 0; 5733ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com fRight = width; 5743ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com fBottom = height; 5753ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com } 5763ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com 57720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com /** 57820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Make the largest representable rectangle 57920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 58020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLargest() { 58120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = fTop = SK_ScalarMin; 58220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fRight = fBottom = SK_ScalarMax; 58320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 584fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 58520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com /** 58620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Make the largest representable rectangle, but inverted (e.g. fLeft will 58720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * be max and right will be min). 58820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 58920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLargestInverted() { 59020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = fTop = SK_ScalarMax; 59120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fRight = fBottom = SK_ScalarMin; 59220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 59320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 5945c404c55772973126d8b3c6942ee42c9361d3fadreed /** 5955c404c55772973126d8b3c6942ee42c9361d3fadreed * Return a new Rect, built as an offset of this rect. 5965c404c55772973126d8b3c6942ee42c9361d3fadreed */ 5975c404c55772973126d8b3c6942ee42c9361d3fadreed SkRect makeOffset(SkScalar dx, SkScalar dy) const { 5985c404c55772973126d8b3c6942ee42c9361d3fadreed return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); 5995c404c55772973126d8b3c6942ee42c9361d3fadreed } 6005c404c55772973126d8b3c6942ee42c9361d3fadreed 6015c404c55772973126d8b3c6942ee42c9361d3fadreed /** 6025c404c55772973126d8b3c6942ee42c9361d3fadreed * Return a new Rect, built as an inset of this rect. 6035c404c55772973126d8b3c6942ee42c9361d3fadreed */ 6045c404c55772973126d8b3c6942ee42c9361d3fadreed SkRect makeInset(SkScalar dx, SkScalar dy) const { 6055c404c55772973126d8b3c6942ee42c9361d3fadreed return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); 6065c404c55772973126d8b3c6942ee42c9361d3fadreed } 6075c404c55772973126d8b3c6942ee42c9361d3fadreed 6088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Offset set the rectangle by adding dx to its left and right, 6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and adding dy to its top and bottom. 6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 611da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void offset(SkScalar dx, SkScalar dy) { 6128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft += dx; 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop += dy; 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight += dx; 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom += dy; 616fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 618da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void offset(const SkPoint& delta) { 619da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com this->offset(delta.fX, delta.fY); 620da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com } 621da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 6224d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com /** 6234d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * Offset this rect such its new x() and y() will equal newX and newY. 6244d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com */ 6254d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com void offsetTo(SkScalar newX, SkScalar newY) { 6264d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fRight += newX - fLeft; 6274d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fBottom += newY - fTop; 6284d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fLeft = newX; 6294d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fTop = newY; 6304d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com } 63172b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 632647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are 633647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com moved inwards, making the rectangle narrower. If dx is negative, then 634647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com the sides are moved outwards, making the rectangle wider. The same holds 635647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com true for dy and the top and bottom. 6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 637da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void inset(SkScalar dx, SkScalar dy) { 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft += dx; 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop += dy; 6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight -= dx; 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom -= dy; 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 644647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are 645647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com moved outwards, making the rectangle wider. If dx is negative, then the 6466623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com sides are moved inwards, making the rectangle narrower. The same holds 647647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com true for dy and the top and bottom. 648647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */ 649647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com void outset(SkScalar dx, SkScalar dy) { this->inset(-dx, -dy); } 650647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If this rectangle intersects r, return true and set this rectangle to that 6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com intersection, otherwise return false and do not change this rectangle. 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, do nothing and return false. 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool intersect(const SkRect& r); 656ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org bool intersect2(const SkRect& r); 6578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If this rectangle intersects the rectangle specified by left, top, right, bottom, 6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true and set this rectangle to that intersection, otherwise return false 6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and do not change this rectangle. 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, do nothing and return false. 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); 6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 665af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 666af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Return true if this rectangle is not empty, and the specified sides of 667af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * a rectangle are not empty, and they intersect. 668af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 669da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const { 6708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return // first check that both are not empty 6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com left < right && top < bottom && 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft < fRight && fTop < fBottom && 6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now check for intersection 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft < right && left < fRight && 6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop < bottom && top < fBottom; 6768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 677f0f617a502ae9298056654811542c62769a906c8reed@google.com 678f0f617a502ae9298056654811542c62769a906c8reed@google.com /** If rectangles a and b intersect, return true and set this rectangle to 679f0f617a502ae9298056654811542c62769a906c8reed@google.com * that intersection, otherwise return false and do not change this 680f0f617a502ae9298056654811542c62769a906c8reed@google.com * rectangle. If either rectangle is empty, do nothing and return false. 681f0f617a502ae9298056654811542c62769a906c8reed@google.com */ 682f0f617a502ae9298056654811542c62769a906c8reed@google.com bool intersect(const SkRect& a, const SkRect& b); 683fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 684af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 685af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Return true if rectangles a and b are not empty and intersect. 686af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 687da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com static bool Intersects(const SkRect& a, const SkRect& b) { 688af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com return !a.isEmpty() && !b.isEmpty() && 689af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com a.fLeft < b.fRight && b.fLeft < a.fRight && 690af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com a.fTop < b.fBottom && b.fTop < a.fBottom; 6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 692fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 693af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 694af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Update this rectangle to enclose itself and the specified rectangle. 695af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * If this rectangle is empty, just set it to the specified rectangle. 696af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * If the specified rectangle is empty, do nothing. 697af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 6988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); 6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 7028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle is empty, do nothing. 7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 704da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void join(const SkRect& r) { 7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 70720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com // alias for join() 70820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void growToInclude(const SkRect& r) { this->join(r); } 70920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 710af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 711af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Grow the rect to include the specified (x,y). After this call, the 712af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * following will be true: fLeft <= x <= fRight && fTop <= y <= fBottom. 713af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * 714af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * This is close, but not quite the same contract as contains(), since 715af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * contains() treats the left and top different from the right and bottom. 716af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * contains(x,y) -> fLeft <= x < fRight && fTop <= y < fBottom. Also note 717af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * that contains(x,y) always returns false if the rect is empty. 718af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 71920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void growToInclude(SkScalar x, SkScalar y) { 72020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = SkMinScalar(x, fLeft); 721ee9aa304579b3d5314519372728187879456d49dbsalomon@google.com fRight = SkMaxScalar(x, fRight); 722ee9aa304579b3d5314519372728187879456d49dbsalomon@google.com fTop = SkMinScalar(y, fTop); 72320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fBottom = SkMaxScalar(y, fBottom); 72420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 725fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 726b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org /** Bulk version of growToInclude */ 727b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org void growToInclude(const SkPoint pts[], int count) { 728b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org this->growToInclude(pts, sizeof(SkPoint), count); 729b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org } 730b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org 731b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org /** Bulk version of growToInclude with stride. */ 732b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org void growToInclude(const SkPoint pts[], size_t stride, int count) { 733b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org SkASSERT(count >= 0); 734b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org SkASSERT(stride >= sizeof(SkPoint)); 735b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org const SkPoint* end = (const SkPoint*)((intptr_t)pts + count * stride); 736b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org for (; pts < end; pts = (const SkPoint*)((intptr_t)pts + stride)) { 737b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org this->growToInclude(pts->fX, pts->fY); 738b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org } 739b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org } 740b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org 741af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 742af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Return true if this rectangle contains r, and if both rectangles are 743af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * not empty. 744af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 745da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool contains(const SkRect& r) const { 7464db592c4085afed2be27a208d778f9ee13e671abreed@google.com // todo: can we eliminate the this->isEmpty check? 747af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com return !r.isEmpty() && !this->isEmpty() && 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft <= r.fLeft && fTop <= r.fTop && 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight >= r.fRight && fBottom >= r.fBottom; 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 752af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 753af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Set the dst rectangle by rounding this rectangle's coordinates to their 754126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com * nearest integer values using SkScalarRoundToInt. 755af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 756da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void round(SkIRect* dst) const { 7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(dst); 7584d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com dst->set(SkScalarRoundToInt(fLeft), SkScalarRoundToInt(fTop), 7594d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com SkScalarRoundToInt(fRight), SkScalarRoundToInt(fBottom)); 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 762af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 7634e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * Variant of round() that explicitly performs the rounding step (i.e. floor(x + 0.5)) using 7644e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * double instead of SkScalar (float). It does this by calling SkDScalarRoundToInt(), which 7654e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * may be slower than calling SkScalarRountToInt(), but gives slightly more accurate results. 7664e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * 7674e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * e.g. 7684e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * SkScalar x = 0.49999997f; 7694e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * int ix = SkScalarRoundToInt(x); 7704e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * SkASSERT(0 == ix); // <--- fails 7714e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * ix = SkDScalarRoundToInt(x); 7724e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * SkASSERT(0 == ix); // <--- succeeds 7734e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org */ 7744e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org void dround(SkIRect* dst) const { 7754e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org SkASSERT(dst); 7764e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org dst->set(SkDScalarRoundToInt(fLeft), SkDScalarRoundToInt(fTop), 7774e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org SkDScalarRoundToInt(fRight), SkDScalarRoundToInt(fBottom)); 7784e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org } 7794e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org 7804e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org /** 781af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Set the dst rectangle by rounding "out" this rectangle, choosing the 782af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * SkScalarFloor of top and left, and the SkScalarCeil of right and bottom. 783af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 784da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void roundOut(SkIRect* dst) const { 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(dst); 7864d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com dst->set(SkScalarFloorToInt(fLeft), SkScalarFloorToInt(fTop), 7874d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com SkScalarCeilToInt(fRight), SkScalarCeilToInt(fBottom)); 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 790af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 791099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com * Expand this rectangle by rounding its coordinates "out", choosing the 792099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com * floor of top and left, and the ceil of right and bottom. If this rect 793099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com * is already on integer coordinates, then it will be unchanged. 794099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com */ 795099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com void roundOut() { 796099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com this->set(SkScalarFloorToScalar(fLeft), 797099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com SkScalarFloorToScalar(fTop), 798099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com SkScalarCeilToScalar(fRight), 799099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com SkScalarCeilToScalar(fBottom)); 800099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com } 801099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com 802099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com /** 8034d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * Set the dst rectangle by rounding "in" this rectangle, choosing the 8044d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * ceil of top and left, and the floor of right and bottom. This does *not* 8054d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * call sort(), so it is possible that the resulting rect is inverted... 8064d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * e.g. left >= right or top >= bottom. Call isEmpty() to detect that. 8074d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com */ 8084d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com void roundIn(SkIRect* dst) const { 8094d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com SkASSERT(dst); 8104d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com dst->set(SkScalarCeilToInt(fLeft), SkScalarCeilToInt(fTop), 8114d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom)); 8124d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com } 81372b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 814126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com /** 815126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com * Return a new SkIRect which is contains the rounded coordinates of this 816126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com * rect using SkScalarRoundToInt. 817126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com */ 818126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com SkIRect round() const { 819126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com SkIRect ir; 820126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com this->round(&ir); 821126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com return ir; 822126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com } 82372b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 8244d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com /** 825af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Swap top/bottom or left/right if there are flipped (i.e. if width() 826af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * or height() would have returned a negative value.) This should be called 827af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * if the edges are computed separately, and may have crossed over each 828af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * other. When this returns, left <= right && top <= bottom 829af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void sort(); 831eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com 832c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com /** 833c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com * cast-safe way to treat the rect as an array of (4) SkScalars. 834c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com */ 835c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com const SkScalar* asScalars() const { return &fLeft; } 836b6b02526438d6839481fb40ccf610d28f7652397bsalomon 837b6b02526438d6839481fb40ccf610d28f7652397bsalomon#ifdef SK_DEVELOPER 838b6b02526438d6839481fb40ccf610d28f7652397bsalomon /** 839b6b02526438d6839481fb40ccf610d28f7652397bsalomon * Dumps the rect using SkDebugf. This is intended for Skia development debugging. Don't 840b6b02526438d6839481fb40ccf610d28f7652397bsalomon * rely on the existence of this function or the formatting of its output. 841b6b02526438d6839481fb40ccf610d28f7652397bsalomon */ 842b6b02526438d6839481fb40ccf610d28f7652397bsalomon void dump() const { 843b6b02526438d6839481fb40ccf610d28f7652397bsalomon SkDebugf("{ l: %f, t: %f, r: %f, b: %f }", fLeft, fTop, fRight, fBottom); 844b6b02526438d6839481fb40ccf610d28f7652397bsalomon } 845b6b02526438d6839481fb40ccf610d28f7652397bsalomon#endif 846b6b02526438d6839481fb40ccf610d28f7652397bsalomon 8478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 850