18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkRect_DEFINED 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkRect_DEFINED 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPoint.h" 12233481ebd0b8644a319443cde33e75266e990ee6reed@android.com#include "SkSize.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1444701df5ce572ac3cccec785cf52103d3d5d14a5joshualittstruct SkRect; 1544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt 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 80157f36d358814a2235aa6284b78a67b725076063reed SkISize size() const { return SkISize::Make(this->width(), this->height()); } 81157f36d358814a2235aa6284b78a67b725076063reed 82c74ab1813013b169ad500fcf1fa62be551041442reed@google.com /** 836898d52c371309d81c2184ea991785d2485323e4reed@google.com * Since the center of an integer rect may fall on a factional value, this 846898d52c371309d81c2184ea991785d2485323e4reed@google.com * method is defined to return (right + left) >> 1. 856898d52c371309d81c2184ea991785d2485323e4reed@google.com * 866898d52c371309d81c2184ea991785d2485323e4reed@google.com * This is a specific "truncation" of the average, which is different than 876898d52c371309d81c2184ea991785d2485323e4reed@google.com * (right + left) / 2 when the sum is negative. 886898d52c371309d81c2184ea991785d2485323e4reed@google.com */ 896898d52c371309d81c2184ea991785d2485323e4reed@google.com int centerX() const { return (fRight + fLeft) >> 1; } 90d9f7503e0cb0c4db856f53b4bdeec1332db6f296skia.committer@gmail.com 916898d52c371309d81c2184ea991785d2485323e4reed@google.com /** 926898d52c371309d81c2184ea991785d2485323e4reed@google.com * Since the center of an integer rect may fall on a factional value, this 936898d52c371309d81c2184ea991785d2485323e4reed@google.com * method is defined to return (bottom + top) >> 1 946898d52c371309d81c2184ea991785d2485323e4reed@google.com * 956898d52c371309d81c2184ea991785d2485323e4reed@google.com * This is a specific "truncation" of the average, which is different than 966898d52c371309d81c2184ea991785d2485323e4reed@google.com * (bottom + top) / 2 when the sum is negative. 976898d52c371309d81c2184ea991785d2485323e4reed@google.com */ 986898d52c371309d81c2184ea991785d2485323e4reed@google.com int centerY() const { return (fBottom + fTop) >> 1; } 99d9f7503e0cb0c4db856f53b4bdeec1332db6f296skia.committer@gmail.com 1006898d52c371309d81c2184ea991785d2485323e4reed@google.com /** 101c74ab1813013b169ad500fcf1fa62be551041442reed@google.com * Return true if the rectangle's width or height are <= 0 102c74ab1813013b169ad500fcf1fa62be551041442reed@google.com */ 103c74ab1813013b169ad500fcf1fa62be551041442reed@google.com bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } 104fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 105194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org bool isLargest() const { return SK_MinS32 == fLeft && 106194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SK_MinS32 == fTop && 107194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SK_MaxS32 == fRight && 108194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org SK_MaxS32 == fBottom; } 109194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 110b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com friend bool operator==(const SkIRect& a, const SkIRect& b) { 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return !memcmp(&a, &b, sizeof(a)); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 113da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 114b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com friend bool operator!=(const SkIRect& a, const SkIRect& b) { 115b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com return !(a == b); 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 118d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com bool is16Bit() const { 119d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com return SkIsS16(fLeft) && SkIsS16(fTop) && 120d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com SkIsS16(fRight) && SkIsS16(fBottom); 121d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com } 122d4577757874d1dda1a3bffa3f2347c251859c27ereed@android.com 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the rectangle to (0,0,0,0) 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setEmpty() { memset(this, 0, sizeof(*this)); } 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 127da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void set(int32_t left, int32_t top, int32_t right, int32_t bottom) { 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = left; 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = top; 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = right; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = bottom; 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com // alias for set(l, t, r, b) 13420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) { 13520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com this->set(left, top, right, bottom); 13620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1381d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) { 1391d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fLeft = x; 1401d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fTop = y; 1411d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fRight = x + width; 1421d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fBottom = y + height; 1431d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com } 14420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 14520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com /** 14620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Make the largest representable rectangle 14720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 14820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLargest() { 14920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = fTop = SK_MinS32; 15020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fRight = fBottom = SK_MaxS32; 15120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 152fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 15320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com /** 15420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Make the largest representable rectangle, but inverted (e.g. fLeft will 15520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * be max 32bit and right will be min 32bit). 15620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 15720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLargestInverted() { 15820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = fTop = SK_MaxS32; 15920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fRight = fBottom = SK_MinS32; 16020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 161fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1625c404c55772973126d8b3c6942ee42c9361d3fadreed /** 1635c404c55772973126d8b3c6942ee42c9361d3fadreed * Return a new IRect, built as an offset of this rect. 1645c404c55772973126d8b3c6942ee42c9361d3fadreed */ 16511fa2247b747eb75e2f158dc7571d458ed6c0115reed SkIRect makeOffset(int32_t dx, int32_t dy) const { 1665c404c55772973126d8b3c6942ee42c9361d3fadreed return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); 1675c404c55772973126d8b3c6942ee42c9361d3fadreed } 1685c404c55772973126d8b3c6942ee42c9361d3fadreed 1695c404c55772973126d8b3c6942ee42c9361d3fadreed /** 1705c404c55772973126d8b3c6942ee42c9361d3fadreed * Return a new IRect, built as an inset of this rect. 1715c404c55772973126d8b3c6942ee42c9361d3fadreed */ 17211fa2247b747eb75e2f158dc7571d458ed6c0115reed SkIRect makeInset(int32_t dx, int32_t dy) const { 1735c404c55772973126d8b3c6942ee42c9361d3fadreed return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); 1745c404c55772973126d8b3c6942ee42c9361d3fadreed } 1755c404c55772973126d8b3c6942ee42c9361d3fadreed 17611fa2247b747eb75e2f158dc7571d458ed6c0115reed /** 17711fa2247b747eb75e2f158dc7571d458ed6c0115reed * Return a new Rect, built as an outset of this rect. 17811fa2247b747eb75e2f158dc7571d458ed6c0115reed */ 17911fa2247b747eb75e2f158dc7571d458ed6c0115reed SkIRect makeOutset(int32_t dx, int32_t dy) const { 18011fa2247b747eb75e2f158dc7571d458ed6c0115reed return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); 18111fa2247b747eb75e2f158dc7571d458ed6c0115reed } 18211fa2247b747eb75e2f158dc7571d458ed6c0115reed 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Offset set the rectangle by adding dx to its left and right, 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and adding dy to its top and bottom. 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 186da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void offset(int32_t dx, int32_t dy) { 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft += dx; 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop += dy; 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight += dx; 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom += dy; 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 193da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void offset(const SkIPoint& delta) { 194da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com this->offset(delta.fX, delta.fY); 195da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com } 196da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 1974d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com /** 1984d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * Offset this rect such its new x() and y() will equal newX and newY. 1994d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com */ 2004d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com void offsetTo(int32_t newX, int32_t newY) { 2014d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fRight += newX - fLeft; 2024d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fBottom += newY - fTop; 2034d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fLeft = newX; 2044d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fTop = newY; 2054d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com } 2064d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards, 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com making the rectangle narrower. If dx is negative, then the sides are moved outwards, 2096623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com making the rectangle wider. The same holds true for dy and the top and bottom. 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 211da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void inset(int32_t dx, int32_t dy) { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft += dx; 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop += dy; 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight -= dx; 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom -= dy; 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 217da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 2186623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are 2196623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com moved outwards, making the rectangle wider. If dx is negative, then the 2206623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com sides are moved inwards, making the rectangle narrower. The same holds 2216623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com true for dy and the top and bottom. 2226623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com */ 2236623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com void outset(int32_t dx, int32_t dy) { this->inset(-dx, -dy); } 2246623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com 22520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com bool quickReject(int l, int t, int r, int b) const { 22620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b; 22720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 228fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if (x,y) is inside the rectangle and the rectangle is not 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com empty. The left and top are considered to be inside, while the right 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and bottom are not. Thus for the rectangle (0, 0, 5, 10), the 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not. 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 234da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool contains(int32_t x, int32_t y) const { 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) && 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (unsigned)(y - fTop) < (unsigned)(fBottom - fTop); 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle. 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, contains() returns false. 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 242da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const { 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return left < right && top < bottom && !this->isEmpty() && // check for empties 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft <= left && fTop <= top && 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight >= right && fBottom >= bottom; 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the specified rectangle r is inside or equal to this rectangle. 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 250da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool contains(const SkIRect& r) const { 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return !r.isEmpty() && !this->isEmpty() && // check for empties 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft <= r.fLeft && fTop <= r.fTop && 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight >= r.fRight && fBottom >= r.fBottom; 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt /** Returns true if the specified rectangle r is inside or equal to this rectangle. 25744701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt */ 25844701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt bool contains(const SkRect& r) const; 25944701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return true if this rectangle contains the specified rectangle. 2615d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com For speed, this method does not check if either this or the specified 2625d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com rectangles are empty, and if either is, its return value is undefined. 2635d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com In the debugging build however, we assert that both this and the 2645d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com specified rectangles are non-empty. 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool containsNoEmptyCheck(int32_t left, int32_t top, 2675d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com int32_t right, int32_t bottom) const { 2685d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com SkASSERT(fLeft < fRight && fTop < fBottom); 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(left < right && top < bottom); 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fLeft <= left && fTop <= top && 2725d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com fRight >= right && fBottom >= bottom; 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 274fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2750d10280190c411b18feb569a2248552047d1aa93reed@google.com bool containsNoEmptyCheck(const SkIRect& r) const { 2760d10280190c411b18feb569a2248552047d1aa93reed@google.com return containsNoEmptyCheck(r.fLeft, r.fTop, r.fRight, r.fBottom); 2770d10280190c411b18feb569a2248552047d1aa93reed@google.com } 278fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If r intersects this rectangle, return true and set this rectangle to that 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com intersection, otherwise return false and do not change this rectangle. 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, do nothing and return false. 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 283f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& r) { 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If rectangles a and b intersect, return true and set this rectangle to 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com that intersection, otherwise return false and do not change this 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle. If either rectangle is empty, do nothing and return false. 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 291f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& a, const SkIRect& b) { 292fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!a.isEmpty() && !b.isEmpty() && 294da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com a.fLeft < b.fRight && b.fLeft < a.fRight && 295da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom) { 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = SkMax32(a.fLeft, b.fLeft); 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = SkMax32(a.fTop, b.fTop); 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = SkMin32(a.fRight, b.fRight); 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = SkMin32(a.fBottom, b.fBottom); 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 304fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If rectangles a and b intersect, return true and set this rectangle to 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com that intersection, otherwise return false and do not change this 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle. For speed, no check to see if a or b are empty is performed. 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either is, then the return result is undefined. In the debug build, 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com we assert that both rectangles are non-empty. 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 311f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips bool SK_WARN_UNUSED_RESULT intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) { 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!a.isEmpty() && !b.isEmpty()); 313fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (a.fLeft < b.fRight && b.fLeft < a.fRight && 315da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom) { 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = SkMax32(a.fLeft, b.fLeft); 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = SkMax32(a.fTop, b.fTop); 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = SkMin32(a.fRight, b.fRight); 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = SkMin32(a.fBottom, b.fBottom); 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If the rectangle specified by left,top,right,bottom intersects this rectangle, 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true and set this rectangle to that intersection, 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com otherwise return false and do not change this rectangle. 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, do nothing and return false. 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 330f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips bool SK_WARN_UNUSED_RESULT intersect(int32_t left, int32_t top, 331f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips int32_t right, int32_t bottom) { 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (left < right && top < bottom && !this->isEmpty() && 333da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com fLeft < right && left < fRight && fTop < bottom && top < fBottom) { 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLeft < left) fLeft = left; 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fTop < top) fTop = top; 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fRight > right) fRight = right; 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fBottom > bottom) fBottom = bottom; 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 342fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if a and b are not empty, and they intersect 3440d10280190c411b18feb569a2248552047d1aa93reed@google.com */ 345da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com static bool Intersects(const SkIRect& a, const SkIRect& b) { 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return !a.isEmpty() && !b.isEmpty() && // check for empties 347f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips a.fLeft < b.fRight && b.fLeft < a.fRight && 348f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips a.fTop < b.fBottom && b.fTop < a.fBottom; 3490d10280190c411b18feb569a2248552047d1aa93reed@google.com } 350fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3510d10280190c411b18feb569a2248552047d1aa93reed@google.com /** 3520d10280190c411b18feb569a2248552047d1aa93reed@google.com * Returns true if a and b intersect. debug-asserts that neither are empty. 3530d10280190c411b18feb569a2248552047d1aa93reed@google.com */ 3540d10280190c411b18feb569a2248552047d1aa93reed@google.com static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b) { 3550d10280190c411b18feb569a2248552047d1aa93reed@google.com SkASSERT(!a.isEmpty()); 3560d10280190c411b18feb569a2248552047d1aa93reed@google.com SkASSERT(!b.isEmpty()); 3570d10280190c411b18feb569a2248552047d1aa93reed@google.com return a.fLeft < b.fRight && b.fLeft < a.fRight && 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a.fTop < b.fBottom && b.fTop < a.fBottom; 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 360fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle is empty, do nothing. 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void join(int32_t left, int32_t top, int32_t right, int32_t bottom); 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle is empty, do nothing. 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 371da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void join(const SkIRect& r) { 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Swap top/bottom or left/right if there are flipped. 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This can be called if the edges are computed separately, 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and may have crossed over each other. 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com When this returns, left <= right && top <= bottom 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void sort(); 38120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 3825d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static const SkIRect& SK_WARN_UNUSED_RESULT EmptyIRect() { 3834b4fb3a52c32cd4937d51d1315624545973b1322reed@google.com static const SkIRect gEmpty = { 0, 0, 0, 0 }; 38420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com return gEmpty; 38520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \struct SkRect 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 3907ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgstruct SK_API SkRect { 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar fLeft, fTop, fRight, fBottom; 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3935d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeEmpty() { 3942687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com SkRect r; 3952687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com r.setEmpty(); 3962687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com return r; 3972687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com } 3982687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com 399b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org static SkRect SK_WARN_UNUSED_RESULT MakeLargest() { 400b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SkRect r; 401b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org r.setLargest(); 402b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org return r; 403b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org } 404b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org 4055d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h) { 4062687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com SkRect r; 4072687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com r.set(0, 0, w, h); 4082687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com return r; 4092687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com } 4102687ae05cbd309072f0b5bb9d872d758108a2776reed@android.com 4110393912de72bc3d8b3640c122c53470dd0da1e6dreed static SkRect SK_WARN_UNUSED_RESULT MakeIWH(int w, int h) { 4120393912de72bc3d8b3640c122c53470dd0da1e6dreed SkRect r; 4130393912de72bc3d8b3640c122c53470dd0da1e6dreed r.set(0, 0, SkIntToScalar(w), SkIntToScalar(h)); 4140393912de72bc3d8b3640c122c53470dd0da1e6dreed return r; 4150393912de72bc3d8b3640c122c53470dd0da1e6dreed } 4160393912de72bc3d8b3640c122c53470dd0da1e6dreed 4175d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size) { 418233481ebd0b8644a319443cde33e75266e990ee6reed@android.com SkRect r; 419233481ebd0b8644a319443cde33e75266e990ee6reed@android.com r.set(0, 0, size.width(), size.height()); 420233481ebd0b8644a319443cde33e75266e990ee6reed@android.com return r; 421233481ebd0b8644a319443cde33e75266e990ee6reed@android.com } 4224d28d9889b033777afc1950474296d37887ef71bskia.committer@gmail.com 4235d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) { 424233481ebd0b8644a319443cde33e75266e990ee6reed@android.com SkRect rect; 425233481ebd0b8644a319443cde33e75266e990ee6reed@android.com rect.set(l, t, r, b); 426233481ebd0b8644a319443cde33e75266e990ee6reed@android.com return rect; 427233481ebd0b8644a319443cde33e75266e990ee6reed@android.com } 428233481ebd0b8644a319443cde33e75266e990ee6reed@android.com 4295d64068a36b190d820afe6108b09fd78c62368dbrobertphillips@google.com static SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) { 430233481ebd0b8644a319443cde33e75266e990ee6reed@android.com SkRect r; 431233481ebd0b8644a319443cde33e75266e990ee6reed@android.com r.set(x, y, x + w, y + h); 4327b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com return r; 4337b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com } 4347b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com 4354469938e92d779dff05e745559e67907bbf21e78reed@google.com SK_ATTR_DEPRECATED("use Make()") 4367b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com static SkRect SK_WARN_UNUSED_RESULT MakeFromIRect(const SkIRect& irect) { 4377b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com SkRect r; 4387b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com r.set(SkIntToScalar(irect.fLeft), 4397b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com SkIntToScalar(irect.fTop), 4407b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com SkIntToScalar(irect.fRight), 4417b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com SkIntToScalar(irect.fBottom)); 442233481ebd0b8644a319443cde33e75266e990ee6reed@android.com return r; 443233481ebd0b8644a319443cde33e75266e990ee6reed@android.com } 44443a6b6a046774576378dfb725e19632a0c8530b7skia.committer@gmail.com 4451d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com static SkRect SK_WARN_UNUSED_RESULT Make(const SkIRect& irect) { 4461d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com SkRect r; 4471d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com r.set(SkIntToScalar(irect.fLeft), 4481d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com SkIntToScalar(irect.fTop), 4491d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com SkIntToScalar(irect.fRight), 4501d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com SkIntToScalar(irect.fBottom)); 4511d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com return r; 4521d6cff7293582c66b1b0a8b3f32ed5d993913d62reed@google.com } 45343a6b6a046774576378dfb725e19632a0c8530b7skia.committer@gmail.com 4541607863b608b7db6c813228768ed5d72997bbc82reed@google.com /** 4551607863b608b7db6c813228768ed5d72997bbc82reed@google.com * Return true if the rectangle's width or height are <= 0 4561607863b608b7db6c813228768ed5d72997bbc82reed@google.com */ 4571607863b608b7db6c813228768ed5d72997bbc82reed@google.com bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } 458fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 459b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org bool isLargest() const { return SK_ScalarMin == fLeft && 460b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SK_ScalarMin == fTop && 461b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SK_ScalarMax == fRight && 462b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org SK_ScalarMax == fBottom; } 463b295fb6ff3222453912dfcb7a1ea5184d40014b5senorblanco@chromium.org 4641607863b608b7db6c813228768ed5d72997bbc82reed@google.com /** 4651607863b608b7db6c813228768ed5d72997bbc82reed@google.com * Returns true iff all values in the rect are finite. If any are 4661607863b608b7db6c813228768ed5d72997bbc82reed@google.com * infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this 4671607863b608b7db6c813228768ed5d72997bbc82reed@google.com * returns false. 4681607863b608b7db6c813228768ed5d72997bbc82reed@google.com */ 4691607863b608b7db6c813228768ed5d72997bbc82reed@google.com bool isFinite() const { 4707b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com float accum = 0; 4717b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com accum *= fLeft; 4727b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com accum *= fTop; 4737b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com accum *= fRight; 4747b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com accum *= fBottom; 475fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4767b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com // accum is either NaN or it is finite (zero). 4776f90475632b0ff8e9e83916ee6373d3c26cc9284ehsan.akhgari SkASSERT(0 == accum || SkScalarIsNaN(accum)); 4787b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com 4791607863b608b7db6c813228768ed5d72997bbc82reed@google.com // value==value will be true iff value is not NaN 4807b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com // TODO: is it faster to say !accum or accum==accum? 4816f90475632b0ff8e9e83916ee6373d3c26cc9284ehsan.akhgari return !SkScalarIsNaN(accum); 4821607863b608b7db6c813228768ed5d72997bbc82reed@google.com } 4831607863b608b7db6c813228768ed5d72997bbc82reed@google.com 484d6195f956fdccef865224520a624e3fd968573d0reed@google.com SkScalar x() const { return fLeft; } 485d6195f956fdccef865224520a624e3fd968573d0reed@google.com SkScalar y() const { return fTop; } 48620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com SkScalar left() const { return fLeft; } 48720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com SkScalar top() const { return fTop; } 48820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com SkScalar right() const { return fRight; } 48920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com SkScalar bottom() const { return fBottom; } 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar width() const { return fRight - fLeft; } 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar height() const { return fBottom - fTop; } 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); } 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); } 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 495e174ea4bb1f07c4d15c50716012e5c8429e9afebbsalomon@google.com friend bool operator==(const SkRect& a, const SkRect& b) { 496e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com return SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4); 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 498da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 499e174ea4bb1f07c4d15c50716012e5c8429e9afebbsalomon@google.com friend bool operator!=(const SkRect& a, const SkRect& b) { 500e1e7d7a6b55504d97ce9f30202a179b63800093breed@google.com return !SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4); 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 50324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org /** return the 4 points that enclose the rectangle (top-left, top-right, bottom-right, 50424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org bottom-left). TODO: Consider adding param to control whether quad is CW or CCW. 50524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org */ 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void toQuad(SkPoint quad[4]) const; 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set this rectangle to the empty rectangle (0,0,0,0) 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setEmpty() { memset(this, 0, sizeof(*this)); } 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 512da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void set(const SkIRect& src) { 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = SkIntToScalar(src.fLeft); 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = SkIntToScalar(src.fTop); 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = SkIntToScalar(src.fRight); 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = SkIntToScalar(src.fBottom); 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 519da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) { 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = left; 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = top; 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = right; 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = bottom; 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 52520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com // alias for set(l, t, r, b) 52620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLTRB(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) { 52720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com this->set(left, top, right, bottom); 52820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 52920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Initialize the rect with the 4 specified integers. The routine handles 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com converting them to scalars (by calling SkIntToScalar) 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void iset(int left, int top, int right, int bottom) { 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft = SkIntToScalar(left); 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop = SkIntToScalar(top); 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight = SkIntToScalar(right); 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom = SkIntToScalar(bottom); 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5406f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com /** 5416f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com * Set this rectangle to be left/top at 0,0, and have the specified width 5426f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com * and height (automatically converted to SkScalar). 5436f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com */ 5446f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com void isetWH(int width, int height) { 5456f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com fLeft = fTop = 0; 5466f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com fRight = SkIntToScalar(width); 5476f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com fBottom = SkIntToScalar(height); 5486f54724c11ab739fa0d6deff1d4b564596fe3970reed@google.com } 5494d28d9889b033777afc1950474296d37887ef71bskia.committer@gmail.com 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set this rectangle to be the bounds of the array of points. 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If the array is empty (count == 0), then set this rectangle 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to the empty rectangle (0,0,0,0) 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 5540bb18bb264b26afca45452910437c09445e23a3creed@google.com void set(const SkPoint pts[], int count) { 5550bb18bb264b26afca45452910437c09445e23a3creed@google.com // set() had been checking for non-finite values, so keep that behavior 5560bb18bb264b26afca45452910437c09445e23a3creed@google.com // for now. Now that we have setBoundsCheck(), we may decide to make 5570bb18bb264b26afca45452910437c09445e23a3creed@google.com // set() be simpler/faster, and not check for those. 5580bb18bb264b26afca45452910437c09445e23a3creed@google.com (void)this->setBoundsCheck(pts, count); 5590bb18bb264b26afca45452910437c09445e23a3creed@google.com } 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56120efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com // alias for set(pts, count) 56220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setBounds(const SkPoint pts[], int count) { 5630bb18bb264b26afca45452910437c09445e23a3creed@google.com (void)this->setBoundsCheck(pts, count); 56420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 565fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 5660bb18bb264b26afca45452910437c09445e23a3creed@google.com /** 5670bb18bb264b26afca45452910437c09445e23a3creed@google.com * Compute the bounds of the array of points, and set this rect to that 5680bb18bb264b26afca45452910437c09445e23a3creed@google.com * bounds and return true... unless a non-finite value is encountered, 5690bb18bb264b26afca45452910437c09445e23a3creed@google.com * in which case this rect is set to empty and false is returned. 5700bb18bb264b26afca45452910437c09445e23a3creed@google.com */ 5710bb18bb264b26afca45452910437c09445e23a3creed@google.com bool setBoundsCheck(const SkPoint pts[], int count); 572fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 5737b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com void set(const SkPoint& p0, const SkPoint& p1) { 5747b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com fLeft = SkMinScalar(p0.fX, p1.fX); 5757b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com fRight = SkMaxScalar(p0.fX, p1.fX); 5767b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com fTop = SkMinScalar(p0.fY, p1.fY); 5777b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com fBottom = SkMaxScalar(p0.fY, p1.fY); 5787b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com } 5797b463acd46b8df866d3a27fbaf69b0090c842d1ereed@google.com 5801d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) { 5811d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fLeft = x; 5821d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fTop = y; 5831d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fRight = x + width; 5841d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com fBottom = y + height; 5851d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com } 5861d12b1fd66e5be27fb4769ee09ce4fcd6bcc5979reed@google.com 5873ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com void setWH(SkScalar width, SkScalar height) { 5883ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com fLeft = 0; 5893ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com fTop = 0; 5903ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com fRight = width; 5913ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com fBottom = height; 5923ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com } 5933ab43d5c5b4d77f46dd0266618f92e5fefce2021bsalomon@google.com 59420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com /** 59520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Make the largest representable rectangle 59620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 59720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLargest() { 59820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = fTop = SK_ScalarMin; 59920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fRight = fBottom = SK_ScalarMax; 60020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 601fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 60220efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com /** 60320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * Make the largest representable rectangle, but inverted (e.g. fLeft will 60420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com * be max and right will be min). 60520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com */ 60620efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void setLargestInverted() { 60720efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = fTop = SK_ScalarMax; 60820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fRight = fBottom = SK_ScalarMin; 60920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 61020efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 6115c404c55772973126d8b3c6942ee42c9361d3fadreed /** 6125c404c55772973126d8b3c6942ee42c9361d3fadreed * Return a new Rect, built as an offset of this rect. 6135c404c55772973126d8b3c6942ee42c9361d3fadreed */ 6145c404c55772973126d8b3c6942ee42c9361d3fadreed SkRect makeOffset(SkScalar dx, SkScalar dy) const { 6155c404c55772973126d8b3c6942ee42c9361d3fadreed return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); 6165c404c55772973126d8b3c6942ee42c9361d3fadreed } 61711fa2247b747eb75e2f158dc7571d458ed6c0115reed 6185c404c55772973126d8b3c6942ee42c9361d3fadreed /** 6195c404c55772973126d8b3c6942ee42c9361d3fadreed * Return a new Rect, built as an inset of this rect. 6205c404c55772973126d8b3c6942ee42c9361d3fadreed */ 6215c404c55772973126d8b3c6942ee42c9361d3fadreed SkRect makeInset(SkScalar dx, SkScalar dy) const { 6225c404c55772973126d8b3c6942ee42c9361d3fadreed return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); 6235c404c55772973126d8b3c6942ee42c9361d3fadreed } 6245c404c55772973126d8b3c6942ee42c9361d3fadreed 62511fa2247b747eb75e2f158dc7571d458ed6c0115reed /** 62611fa2247b747eb75e2f158dc7571d458ed6c0115reed * Return a new Rect, built as an outset of this rect. 62711fa2247b747eb75e2f158dc7571d458ed6c0115reed */ 62811fa2247b747eb75e2f158dc7571d458ed6c0115reed SkRect makeOutset(SkScalar dx, SkScalar dy) const { 62911fa2247b747eb75e2f158dc7571d458ed6c0115reed return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); 63011fa2247b747eb75e2f158dc7571d458ed6c0115reed } 63111fa2247b747eb75e2f158dc7571d458ed6c0115reed 6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Offset set the rectangle by adding dx to its left and right, 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and adding dy to its top and bottom. 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 635da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void offset(SkScalar dx, SkScalar dy) { 6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft += dx; 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop += dy; 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight += dx; 6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom += dy; 640fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com } 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 642da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void offset(const SkPoint& delta) { 643da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com this->offset(delta.fX, delta.fY); 644da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com } 645da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com 6464d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com /** 6474d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * Offset this rect such its new x() and y() will equal newX and newY. 6484d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com */ 6494d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com void offsetTo(SkScalar newX, SkScalar newY) { 6504d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fRight += newX - fLeft; 6514d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fBottom += newY - fTop; 6524d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fLeft = newX; 6534d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com fTop = newY; 6544d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com } 65572b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 656647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are 657647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com moved inwards, making the rectangle narrower. If dx is negative, then 658647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com the sides are moved outwards, making the rectangle wider. The same holds 659647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com true for dy and the top and bottom. 6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 661da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void inset(SkScalar dx, SkScalar dy) { 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft += dx; 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTop += dy; 6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight -= dx; 6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fBottom -= dy; 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 668647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are 669647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com moved outwards, making the rectangle wider. If dx is negative, then the 6706623fcd1ee33b35fa18e304e9c76272faa603cbfrobertphillips@google.com sides are moved inwards, making the rectangle narrower. The same holds 671647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com true for dy and the top and bottom. 672647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com */ 673647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com void outset(SkScalar dx, SkScalar dy) { this->inset(-dx, -dy); } 674647a804c3dd53b6743091ec97dd12111f90efec3bsalomon@google.com 6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If this rectangle intersects r, return true and set this rectangle to that 6768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com intersection, otherwise return false and do not change this rectangle. 6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, do nothing and return false. 6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 679f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips bool SK_WARN_UNUSED_RESULT intersect(const SkRect& r); 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If this rectangle intersects the rectangle specified by left, top, right, bottom, 6828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true and set this rectangle to that intersection, otherwise return false 6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and do not change this rectangle. 6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If either rectangle is empty, do nothing and return false. 6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 686f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips bool SK_WARN_UNUSED_RESULT intersect(SkScalar left, SkScalar top, 687f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips SkScalar right, SkScalar bottom); 6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 689af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 6901119c870651ccd34c0acb8fb2cdfad2c07d3116creed * If rectangles a and b intersect, return true and set this rectangle to 6911119c870651ccd34c0acb8fb2cdfad2c07d3116creed * that intersection, otherwise return false and do not change this 6921119c870651ccd34c0acb8fb2cdfad2c07d3116creed * rectangle. If either rectangle is empty, do nothing and return false. 6931119c870651ccd34c0acb8fb2cdfad2c07d3116creed */ 694f4e5995ac70d4614e0a05b92a8a03e2b7d76bd9crobertphillips bool SK_WARN_UNUSED_RESULT intersect(const SkRect& a, const SkRect& b); 6951119c870651ccd34c0acb8fb2cdfad2c07d3116creed 6961119c870651ccd34c0acb8fb2cdfad2c07d3116creed 6971119c870651ccd34c0acb8fb2cdfad2c07d3116creedprivate: 6981119c870651ccd34c0acb8fb2cdfad2c07d3116creed static bool Intersects(SkScalar al, SkScalar at, SkScalar ar, SkScalar ab, 6991119c870651ccd34c0acb8fb2cdfad2c07d3116creed SkScalar bl, SkScalar bt, SkScalar br, SkScalar bb) { 7001119c870651ccd34c0acb8fb2cdfad2c07d3116creed SkScalar L = SkMaxScalar(al, bl); 7011119c870651ccd34c0acb8fb2cdfad2c07d3116creed SkScalar R = SkMinScalar(ar, br); 7021119c870651ccd34c0acb8fb2cdfad2c07d3116creed SkScalar T = SkMaxScalar(at, bt); 7031119c870651ccd34c0acb8fb2cdfad2c07d3116creed SkScalar B = SkMinScalar(ab, bb); 7041119c870651ccd34c0acb8fb2cdfad2c07d3116creed return L < R && T < B; 7051119c870651ccd34c0acb8fb2cdfad2c07d3116creed } 7061119c870651ccd34c0acb8fb2cdfad2c07d3116creed 7071119c870651ccd34c0acb8fb2cdfad2c07d3116creedpublic: 7081119c870651ccd34c0acb8fb2cdfad2c07d3116creed /** 709af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Return true if this rectangle is not empty, and the specified sides of 710af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * a rectangle are not empty, and they intersect. 711af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 712da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const { 7131119c870651ccd34c0acb8fb2cdfad2c07d3116creed return Intersects(fLeft, fTop, fRight, fBottom, left, top, right, bottom); 7148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 715f0f617a502ae9298056654811542c62769a906c8reed@google.com 716a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed bool intersects(const SkRect& r) const { 717a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed return Intersects(fLeft, fTop, fRight, fBottom, 718a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed r.fLeft, r.fTop, r.fRight, r.fBottom); 719a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 720a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 721af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 722af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Return true if rectangles a and b are not empty and intersect. 723af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 724da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com static bool Intersects(const SkRect& a, const SkRect& b) { 7251119c870651ccd34c0acb8fb2cdfad2c07d3116creed return Intersects(a.fLeft, a.fTop, a.fRight, a.fBottom, 7261119c870651ccd34c0acb8fb2cdfad2c07d3116creed b.fLeft, b.fTop, b.fRight, b.fBottom); 7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 728fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 729af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 730af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Update this rectangle to enclose itself and the specified rectangle. 731af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * If this rectangle is empty, just set it to the specified rectangle. 732af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * If the specified rectangle is empty, do nothing. 733af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); 7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Update this rectangle to enclose itself and the specified rectangle. 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com If this rectangle is empty, just set it to the specified rectangle. If the specified 7388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rectangle is empty, do nothing. 7398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 740da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void join(const SkRect& r) { 7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); 7428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 74310d0327c16bb748d6f73eb37dd2341c61e47ca8creed 74410d0327c16bb748d6f73eb37dd2341c61e47ca8creed void joinNonEmptyArg(const SkRect& r) { 74510d0327c16bb748d6f73eb37dd2341c61e47ca8creed SkASSERT(!r.isEmpty()); 74610d0327c16bb748d6f73eb37dd2341c61e47ca8creed // if we are empty, just assign 74710d0327c16bb748d6f73eb37dd2341c61e47ca8creed if (fLeft >= fRight || fTop >= fBottom) { 74810d0327c16bb748d6f73eb37dd2341c61e47ca8creed *this = r; 74910d0327c16bb748d6f73eb37dd2341c61e47ca8creed } else { 7503dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt this->joinPossiblyEmptyRect(r); 75110d0327c16bb748d6f73eb37dd2341c61e47ca8creed } 75210d0327c16bb748d6f73eb37dd2341c61e47ca8creed } 75320efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com 754af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 7553dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt * Joins the rectangle with another without checking if either are empty (may produce unexpected 7563dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt * results if either rect is inverted). 7573dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt */ 7583dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt void joinPossiblyEmptyRect(const SkRect& r) { 7593dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt fLeft = SkMinScalar(fLeft, r.left()); 7603dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt fTop = SkMinScalar(fTop, r.top()); 7613dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt fRight = SkMaxScalar(fRight, r.right()); 7623dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt fBottom = SkMaxScalar(fBottom, r.bottom()); 7633dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt } 7643dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt 7653dc2ccae6c0f0cf6ac951585a197bfb8a58cfee5joshualitt /** 766af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Grow the rect to include the specified (x,y). After this call, the 767af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * following will be true: fLeft <= x <= fRight && fTop <= y <= fBottom. 768af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * 769af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * This is close, but not quite the same contract as contains(), since 770af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * contains() treats the left and top different from the right and bottom. 771af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * contains(x,y) -> fLeft <= x < fRight && fTop <= y < fBottom. Also note 772af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * that contains(x,y) always returns false if the rect is empty. 773af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 77420efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com void growToInclude(SkScalar x, SkScalar y) { 77520efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fLeft = SkMinScalar(x, fLeft); 776ee9aa304579b3d5314519372728187879456d49dbsalomon@google.com fRight = SkMaxScalar(x, fRight); 777ee9aa304579b3d5314519372728187879456d49dbsalomon@google.com fTop = SkMinScalar(y, fTop); 77820efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com fBottom = SkMaxScalar(y, fBottom); 77920efde71b4fd28691b10c8f1cfe15cb2aafddaeareed@google.com } 780fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 781b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org /** Bulk version of growToInclude */ 782b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org void growToInclude(const SkPoint pts[], int count) { 783b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org this->growToInclude(pts, sizeof(SkPoint), count); 784b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org } 785b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org 786b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org /** Bulk version of growToInclude with stride. */ 787b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org void growToInclude(const SkPoint pts[], size_t stride, int count) { 788b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org SkASSERT(count >= 0); 789b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org SkASSERT(stride >= sizeof(SkPoint)); 790b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org const SkPoint* end = (const SkPoint*)((intptr_t)pts + count * stride); 791b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org for (; pts < end; pts = (const SkPoint*)((intptr_t)pts + stride)) { 792b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org this->growToInclude(pts->fX, pts->fY); 793b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org } 794b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org } 795b8bd6cbbcde9846094ade18cafadfad46dc00889commit-bot@chromium.org 796af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 797af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Return true if this rectangle contains r, and if both rectangles are 798af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * not empty. 799af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 800da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com bool contains(const SkRect& r) const { 8014db592c4085afed2be27a208d778f9ee13e671abreed@google.com // todo: can we eliminate the this->isEmpty check? 802af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com return !r.isEmpty() && !this->isEmpty() && 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft <= r.fLeft && fTop <= r.fTop && 8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRight >= r.fRight && fBottom >= r.fBottom; 8058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 807af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 808570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt * Returns true if the specified rectangle r is inside or equal to this rectangle. 809570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt */ 810570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt bool contains(const SkIRect& r) const { 811570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt // todo: can we eliminate the this->isEmpty check? 812570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt return !r.isEmpty() && !this->isEmpty() && 813570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt fLeft <= SkIntToScalar(r.fLeft) && fTop <= SkIntToScalar(r.fTop) && 814570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt fRight >= SkIntToScalar(r.fRight) && fBottom >= SkIntToScalar(r.fBottom); 815570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt } 816570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt 817570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt /** 818af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Set the dst rectangle by rounding this rectangle's coordinates to their 819126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com * nearest integer values using SkScalarRoundToInt. 820af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 821da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void round(SkIRect* dst) const { 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(dst); 8234d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com dst->set(SkScalarRoundToInt(fLeft), SkScalarRoundToInt(fTop), 8244d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com SkScalarRoundToInt(fRight), SkScalarRoundToInt(fBottom)); 8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 827af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 8284e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * Variant of round() that explicitly performs the rounding step (i.e. floor(x + 0.5)) using 8294e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * double instead of SkScalar (float). It does this by calling SkDScalarRoundToInt(), which 8304e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * may be slower than calling SkScalarRountToInt(), but gives slightly more accurate results. 8314e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * 8324e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * e.g. 8334e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * SkScalar x = 0.49999997f; 8344e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * int ix = SkScalarRoundToInt(x); 8354e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * SkASSERT(0 == ix); // <--- fails 8364e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * ix = SkDScalarRoundToInt(x); 8374e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org * SkASSERT(0 == ix); // <--- succeeds 8384e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org */ 8394e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org void dround(SkIRect* dst) const { 8404e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org SkASSERT(dst); 8414e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org dst->set(SkDScalarRoundToInt(fLeft), SkDScalarRoundToInt(fTop), 8424e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org SkDScalarRoundToInt(fRight), SkDScalarRoundToInt(fBottom)); 8434e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org } 8444e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org 8454e332f82fce0126045e9cb2ef0a2097a6c4c40a3commit-bot@chromium.org /** 846af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Set the dst rectangle by rounding "out" this rectangle, choosing the 847af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * SkScalarFloor of top and left, and the SkScalarCeil of right and bottom. 848af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 849da6fb3246a4f3e7e835f23b4834affb80bb613fareed@android.com void roundOut(SkIRect* dst) const { 8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(dst); 8514d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com dst->set(SkScalarFloorToInt(fLeft), SkScalarFloorToInt(fTop), 8524d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com SkScalarCeilToInt(fRight), SkScalarCeilToInt(fBottom)); 8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 855af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com /** 856b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed * Set the dst rectangle by rounding "out" this rectangle, choosing the 857b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed * SkScalarFloorToScalar of top and left, and the SkScalarCeilToScalar of right and bottom. 858d02cf2664d0e453a6ec57cddc7f09bfc07fd91dbreed * 859d02cf2664d0e453a6ec57cddc7f09bfc07fd91dbreed * It is safe for this == dst 860099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com */ 861d02cf2664d0e453a6ec57cddc7f09bfc07fd91dbreed void roundOut(SkRect* dst) const { 862d02cf2664d0e453a6ec57cddc7f09bfc07fd91dbreed dst->set(SkScalarFloorToScalar(fLeft), 863d02cf2664d0e453a6ec57cddc7f09bfc07fd91dbreed SkScalarFloorToScalar(fTop), 864d02cf2664d0e453a6ec57cddc7f09bfc07fd91dbreed SkScalarCeilToScalar(fRight), 865d02cf2664d0e453a6ec57cddc7f09bfc07fd91dbreed SkScalarCeilToScalar(fBottom)); 866099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com } 867099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com 868099d22dbce650abdda0c5c5a7ee89ee0850897f1reed@google.com /** 8694d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * Set the dst rectangle by rounding "in" this rectangle, choosing the 8704d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * ceil of top and left, and the floor of right and bottom. This does *not* 8714d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * call sort(), so it is possible that the resulting rect is inverted... 8724d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com * e.g. left >= right or top >= bottom. Call isEmpty() to detect that. 8734d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com */ 8744d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com void roundIn(SkIRect* dst) const { 8754d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com SkASSERT(dst); 8764d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com dst->set(SkScalarCeilToInt(fLeft), SkScalarCeilToInt(fTop), 8774d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom)); 8784d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com } 87972b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com 880b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed //! Returns the result of calling round(&dst) 881126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com SkIRect round() const { 882126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com SkIRect ir; 883126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com this->round(&ir); 884126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com return ir; 885126f7f5244502c0cbf1e5fec1d2ad7a0f2eb6c34reed@google.com } 886b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed 887b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed //! Returns the result of calling roundOut(&dst) 888b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed SkIRect roundOut() const { 889b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed SkIRect ir; 890b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed this->roundOut(&ir); 891b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed return ir; 892b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed } 893b07a94f1cba3976596ae1a7f23d8c2043ba353f3reed 8944d3038379d98074612a92ef2bc85250cd205cfa9reed@google.com /** 895af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * Swap top/bottom or left/right if there are flipped (i.e. if width() 896af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * or height() would have returned a negative value.) This should be called 897af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * if the edges are computed separately, and may have crossed over each 898af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com * other. When this returns, left <= right && top <= bottom 899af8edcc477ad36592adcf53d14e8bf4441143b31reed@google.com */ 90040636a53037eadd957b8e43f0961f640aaa93e84reed void sort() { 901fb502f072f5a32ad122bfc2717fe56a3c22e482eqiankun.miao if (fLeft > fRight) { 902fb502f072f5a32ad122bfc2717fe56a3c22e482eqiankun.miao SkTSwap<SkScalar>(fLeft, fRight); 903fb502f072f5a32ad122bfc2717fe56a3c22e482eqiankun.miao } 904fb502f072f5a32ad122bfc2717fe56a3c22e482eqiankun.miao 905fb502f072f5a32ad122bfc2717fe56a3c22e482eqiankun.miao if (fTop > fBottom) { 906fb502f072f5a32ad122bfc2717fe56a3c22e482eqiankun.miao SkTSwap<SkScalar>(fTop, fBottom); 907fb502f072f5a32ad122bfc2717fe56a3c22e482eqiankun.miao } 90840636a53037eadd957b8e43f0961f640aaa93e84reed } 909eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com 910c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com /** 911c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com * cast-safe way to treat the rect as an array of (4) SkScalars. 912c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com */ 913c7d0ea3cd328566958bfcb86b4488dcbb94dd5ecreed@google.com const SkScalar* asScalars() const { return &fLeft; } 914b6b02526438d6839481fb40ccf610d28f7652397bsalomon 915e05fed0d6339c63c8cceff74af0b8d120c07e54creed void dump(bool asHex) const; 916e05fed0d6339c63c8cceff74af0b8d120c07e54creed void dump() const { this->dump(false); } 917e05fed0d6339c63c8cceff74af0b8d120c07e54creed void dumpHex() const { this->dump(true); } 9188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 9198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 92044701df5ce572ac3cccec785cf52103d3d5d14a5joshualittinline bool SkIRect::contains(const SkRect& r) const { 92144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt return !r.isEmpty() && !this->isEmpty() && // check for empties 92244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt (SkScalar)fLeft <= r.fLeft && (SkScalar)fTop <= r.fTop && 92344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt (SkScalar)fRight >= r.fRight && (SkScalar)fBottom >= r.fBottom; 92444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt} 92544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt 9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 927