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#include "SkRect.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1291a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.comvoid SkIRect::join(int32_t left, int32_t top, int32_t right, int32_t bottom) { 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // do nothing if the params are empty 1491a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com if (left >= right || top >= bottom) { 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 1691a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com } 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we are empty, just assign 1991a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com if (fLeft >= fRight || fTop >= fBottom) { 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->set(left, top, right, bottom); 2191a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com } else { 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (left < fLeft) fLeft = left; 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (top < fTop) fTop = top; 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (right > fRight) fRight = right; 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bottom > fBottom) fBottom = bottom; 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2991a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.comvoid SkIRect::sort() { 3091a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com if (fLeft > fRight) { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTSwap<int32_t>(fLeft, fRight); 3291a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com } 3391a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com if (fTop > fBottom) { 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTSwap<int32_t>(fTop, fBottom); 3591a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com } 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////// 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4091a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.comvoid SkRect::sort() { 4191a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com if (fLeft > fRight) { 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTSwap<SkScalar>(fLeft, fRight); 4391a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com } 4491a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com if (fTop > fBottom) { 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTSwap<SkScalar>(fTop, fBottom); 4691a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com } 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4991a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.comvoid SkRect::toQuad(SkPoint quad[4]) const { 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(quad); 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com quad[0].set(fLeft, fTop); 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com quad[1].set(fRight, fTop); 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com quad[2].set(fRight, fBottom); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com quad[3].set(fLeft, fBottom); 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 580bb18bb264b26afca45452910437c09445e23a3creed@google.combool SkRect::setBoundsCheck(const SkPoint pts[], int count) { 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((pts && count > 0) || count == 0); 60fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 610bb18bb264b26afca45452910437c09445e23a3creed@google.com bool isFinite = true; 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count <= 0) { 644516f4786f5dda1b86a8f825b9e8e910d9c2363creed@android.com sk_bzero(this, sizeof(SkRect)); 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar l, t, r, b; 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com l = r = pts[0].fX; 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com t = b = pts[0].fY; 7030d90ebe7c05b7067f5c67bd8278371c2a355b02reed@google.com 7130d90ebe7c05b7067f5c67bd8278371c2a355b02reed@google.com // If all of the points are finite, accum should stay 0. If we encounter 7230d90ebe7c05b7067f5c67bd8278371c2a355b02reed@google.com // a NaN or infinity, then accum should become NaN. 738f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com float accum = 0; 748f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com accum *= l; accum *= t; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 1; i < count; i++) { 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x = pts[i].fX; 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar y = pts[i].fY; 7930d90ebe7c05b7067f5c67bd8278371c2a355b02reed@google.com 808f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com accum *= x; accum *= y; 818f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com 828f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com // we use if instead of if/else, so we can generate min/max 838f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com // float instructions (at least on SSE) 848f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com if (x < l) l = x; 858f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com if (x > r) r = x; 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 878f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com if (y < t) t = y; 888f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com if (y > b) b = y; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 90fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com 9130d90ebe7c05b7067f5c67bd8278371c2a355b02reed@google.com SkASSERT(!accum || !SkScalarIsFinite(accum)); 9230d90ebe7c05b7067f5c67bd8278371c2a355b02reed@google.com if (accum) { 93fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com l = t = r = b = 0; 940bb18bb264b26afca45452910437c09445e23a3creed@google.com isFinite = false; 95fe701129857924f76a0d752d4c964b3c5e4b49fereed@google.com } 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->set(l, t, r, b); 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 98fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 990bb18bb264b26afca45452910437c09445e23a3creed@google.com return isFinite; 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10291a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.combool SkRect::intersect(SkScalar left, SkScalar top, SkScalar right, 10391a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com SkScalar bottom) { 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (left < right && top < bottom && !this->isEmpty() && // check for empties 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLeft < right && left < fRight && fTop < bottom && top < fBottom) 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fLeft < left) fLeft = left; 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fTop < top) fTop = top; 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fRight > right) fRight = right; 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fBottom > bottom) fBottom = bottom; 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11691a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.combool SkRect::intersect(const SkRect& r) { 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 120ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.orgbool SkRect::intersect2(const SkRect& r) { 121ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org SkScalar L = SkMaxScalar(fLeft, r.fLeft); 122ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org SkScalar R = SkMinScalar(fRight, r.fRight); 123ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org if (L >= R) { 124ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org return false; 125ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org } 126ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org SkScalar T = SkMaxScalar(fTop, r.fTop); 127ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org SkScalar B = SkMinScalar(fBottom, r.fBottom); 128ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org if (T >= B) { 129ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org return false; 130ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org } 131ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org this->set(L, T, R, B); 132ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org return true; 133ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org} 134ae8f9528fd0052e06653272abb44a1f49a3b726bmike@reedtribe.org 135f0f617a502ae9298056654811542c62769a906c8reed@google.combool SkRect::intersect(const SkRect& a, const SkRect& b) { 136f0f617a502ae9298056654811542c62769a906c8reed@google.com 137f0f617a502ae9298056654811542c62769a906c8reed@google.com if (!a.isEmpty() && !b.isEmpty() && 138f0f617a502ae9298056654811542c62769a906c8reed@google.com a.fLeft < b.fRight && b.fLeft < a.fRight && 139f0f617a502ae9298056654811542c62769a906c8reed@google.com a.fTop < b.fBottom && b.fTop < a.fBottom) { 140f0f617a502ae9298056654811542c62769a906c8reed@google.com fLeft = SkMaxScalar(a.fLeft, b.fLeft); 141f0f617a502ae9298056654811542c62769a906c8reed@google.com fTop = SkMaxScalar(a.fTop, b.fTop); 142f0f617a502ae9298056654811542c62769a906c8reed@google.com fRight = SkMinScalar(a.fRight, b.fRight); 143f0f617a502ae9298056654811542c62769a906c8reed@google.com fBottom = SkMinScalar(a.fBottom, b.fBottom); 144f0f617a502ae9298056654811542c62769a906c8reed@google.com return true; 145f0f617a502ae9298056654811542c62769a906c8reed@google.com } 146f0f617a502ae9298056654811542c62769a906c8reed@google.com return false; 147f0f617a502ae9298056654811542c62769a906c8reed@google.com} 148f0f617a502ae9298056654811542c62769a906c8reed@google.com 14991a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.comvoid SkRect::join(SkScalar left, SkScalar top, SkScalar right, 15091a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com SkScalar bottom) { 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // do nothing if the params are empty 15291a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com if (left >= right || top >= bottom) { 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 15491a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com } 155077910e20cda41d7981084fbd047a108894bc8dfreed@google.com 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we are empty, just assign 15791a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com if (fLeft >= fRight || fTop >= fBottom) { 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->set(left, top, right, bottom); 15991a2ae988e46b8db3f1cc691d09d77f8c5d84d2creed@google.com } else { 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (left < fLeft) fLeft = left; 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (top < fTop) fTop = top; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (right > fRight) fRight = right; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bottom > fBottom) fBottom = bottom; 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 166