15985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com/* 25985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Copyright 2012 Google Inc. 35985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * 45985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 55985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * found in the LICENSE file. 65985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 75985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 85985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com#ifndef SkRRect_DEFINED 95985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com#define SkRRect_DEFINED 105985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 115985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com#include "SkRect.h" 125985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com#include "SkPoint.h" 135985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comclass SkPath; 1520e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.comclass SkMatrix; 164ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 175985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// Path forward: 185985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// core work 195985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// add validate method (all radii positive, all radii sums < rect size, etc.) 205985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// add contains(SkRect&) - for clip stack 215985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// add contains(SkRRect&) - for clip stack 225985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// add heart rect computation (max rect inside RR) 235985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// add 9patch rect computation 245985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// add growToInclude(SkPath&) 255985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// analysis 265985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// use growToInclude to fit skp round rects & generate stats (RRs vs. real paths) 275985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// check on # of rectorus's the RRs could handle 285985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// rendering work 2914e50ae2a1b1cccdace599247b8c788b8db33ef4commit-bot@chromium.org// update SkPath.addRRect() to only use quads 305985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// add GM and bench 315985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// further out 325985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com// detect and triangulate RRectorii rather than falling back to SW in Ganesh 33c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com// 345985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 355985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com/** \class SkRRect 365985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 37c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com The SkRRect class represents a rounded rect with a potentially different 38c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com radii for each corner. It does not have a constructor so must be 39c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com initialized with one of the initialization functions (e.g., setEmpty, 405985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com setRectRadii, etc.) 415985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 42c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com This class is intended to roughly match CSS' border-*-*-radius capabilities. 435985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com This means: 44c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com If either of a corner's radii are 0 the corner will be square. 455985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com Negative radii are not allowed (they are clamped to zero). 465985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com If the corner curves overlap they will be proportionally reduced to fit. 475985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com*/ 485985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.comclass SK_API SkRRect { 495985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.compublic: 50c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 515985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Enum to capture the various possible subtypes of RR. Accessed 525985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * by type(). The subtypes become progressively less restrictive. 535985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 545985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com enum Type { 550da23a5184cf8ee658c4f1ac45b798ddf7e73002tomhudson@google.com // !< Internal indicator that the sub type must be computed. 560da23a5184cf8ee658c4f1ac45b798ddf7e73002tomhudson@google.com kUnknown_Type = -1, 570da23a5184cf8ee658c4f1ac45b798ddf7e73002tomhudson@google.com 585985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com // !< The RR is empty 595985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kEmpty_Type, 605985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 615985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< The RR is actually a (non-empty) rect (i.e., at least one radius 625985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< at each corner is zero) 63c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com kRect_Type, 645985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 65c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com //!< The RR is actually a (non-empty) oval (i.e., all x radii are equal 665985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< and >= width/2 and all the y radii are equal and >= height/2 67c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com kOval_Type, 685985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 69c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com //!< The RR is non-empty and all the x radii are equal & all y radii 70c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com //!< are equal but it is not an oval (i.e., there are lines between 715985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< the curves) nor a rect (i.e., both radii are non-zero) 72c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com kSimple_Type, 735985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 74f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< The RR is non-empty and the two left x radii are equal, the two top 75f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< y radii are equal, and the same for the right and bottom but it is 76f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< neither an rect, oval, nor a simple RR. It is called "nine patch" 77f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< because the centers of the corner ellipses form an axis aligned 78f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< rect with edges that divide the RR into an 9 rectangular patches: 79f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< an interior patch, four edge patches, and four corner patches. 80f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org kNinePatch_Type, 81f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org 825985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< A fully general (non-empty) RR. Some of the x and/or y radii are 835985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< different from the others and there must be one corner where 845985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< both radii are non-zero. 855985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kComplex_Type, 865985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com }; 875985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 88c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 895985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Returns the RR's sub type. 905985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 914ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com Type getType() const { 925985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(this->validate();) 935985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 945985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com if (kUnknown_Type == fType) { 955985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com this->computeType(); 965985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 975985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkASSERT(kUnknown_Type != fType); 985985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return fType; 995985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1005985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1014ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com Type type() const { return this->getType(); } 1024ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1034ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isEmpty() const { return kEmpty_Type == this->getType(); } 1044ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isRect() const { return kRect_Type == this->getType(); } 1054ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isOval() const { return kOval_Type == this->getType(); } 1064ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isSimple() const { return kSimple_Type == this->getType(); } 107c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org inline bool isSimpleCircular() const { 108c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org return this->isSimple() && fRadii[0].fX == fRadii[0].fY; 109c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org } 110f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org inline bool isNinePatch() const { return kNinePatch_Type == this->getType(); } 1114ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isComplex() const { return kComplex_Type == this->getType(); } 1124ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 113821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org bool allCornersCircular() const; 114821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org 11537071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org SkScalar width() const { return fRect.width(); } 11637071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org SkScalar height() const { return fRect.height(); } 11737071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org 118c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 1195985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Set this RR to the empty rectangle (0,0,0,0) with 0 x & y radii. 1205985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 121c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com void setEmpty() { 1225985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fRect.setEmpty(); 1235985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com memset(fRadii, 0, sizeof(fRadii)); 1245985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fType = kEmpty_Type; 1255985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1265985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(this->validate();) 1275985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1285985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 129c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 1305985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Set this RR to match the supplied rect. All radii will be 0. 1315985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 1325985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void setRect(const SkRect& rect) { 1335985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com if (rect.isEmpty()) { 1345985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com this->setEmpty(); 1355985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return; 1365985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1375985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1385985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fRect = rect; 1395985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com memset(fRadii, 0, sizeof(fRadii)); 1405985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fType = kRect_Type; 1415985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1425985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(this->validate();) 1435985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1445985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 145c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 1465985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Set this RR to match the supplied oval. All x radii will equal half the 1475985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * width and all y radii will equal half the height. 1485985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 1495985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void setOval(const SkRect& oval) { 1505985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com if (oval.isEmpty()) { 1515985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com this->setEmpty(); 1525985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return; 1535985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1545985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1555985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkScalar xRad = SkScalarHalf(oval.width()); 1565985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkScalar yRad = SkScalarHalf(oval.height()); 1575985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1585985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fRect = oval; 1595985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com for (int i = 0; i < 4; ++i) { 1605985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fRadii[i].set(xRad, yRad); 1615985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1625985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fType = kOval_Type; 1635985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1645985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(this->validate();) 1655985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1665985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 167c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 1685985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Initialize the RR with the same radii for all four corners. 1695985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 1705985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad); 1715985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 172c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 173f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org * Initialize the rr with one radius per-side. 174f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org */ 175f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org void setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad, 176f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org SkScalar rightRad, SkScalar bottomRad); 177f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org 178f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org /** 1795985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Initialize the RR with potentially different radii for all four corners. 1805985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 1815985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void setRectRadii(const SkRect& rect, const SkVector radii[4]); 1825985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 183c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com // The radii are stored in UL, UR, LR, LL order. 1845985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com enum Corner { 1855985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kUpperLeft_Corner, 1865985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kUpperRight_Corner, 1875985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kLowerRight_Corner, 1885985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kLowerLeft_Corner 1895985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com }; 1905985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1915985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com const SkRect& rect() const { return fRect; } 1925985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com const SkVector& radii(Corner corner) const { return fRadii[corner]; } 1934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com const SkRect& getBounds() const { return fRect; } 1944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 1954ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com /** 1964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * When a rrect is simple, all of its radii are equal. This returns one 1974ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * of those radii. This call requires the rrect to be non-complex. 1984ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com */ 1994ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com const SkVector& getSimpleRadii() const { 2004ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkASSERT(!this->isComplex()); 2014ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return fRadii[0]; 2024ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2035985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2045985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com friend bool operator==(const SkRRect& a, const SkRRect& b) { 2055985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return a.fRect == b.fRect && 2064bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com SkScalarsEqual(a.fRadii[0].asScalars(), 2074bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com b.fRadii[0].asScalars(), 8); 2085985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 2095985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2105985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com friend bool operator!=(const SkRRect& a, const SkRRect& b) { 2115985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return a.fRect != b.fRect || 2124bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com !SkScalarsEqual(a.fRadii[0].asScalars(), 2134bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com b.fRadii[0].asScalars(), 8); 2145985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 2155985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2165985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com /** 217bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * Call inset on the bounds, and adjust the radii to reflect what happens 218bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * in stroking: If the corner is sharp (no curvature), leave it alone, 219bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * otherwise we grow/shrink the radii by the amount of the inset. If a 220bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * given radius becomes negative, it is pinned to 0. 221bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * 222bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * It is valid for dst == this. 223bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org */ 22437071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org void inset(SkScalar dx, SkScalar dy, SkRRect* dst) const; 225bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org 22637071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org void inset(SkScalar dx, SkScalar dy) { 22737071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org this->inset(dx, dy, this); 22837071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org } 229bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org 230bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org /** 231bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * Call outset on the bounds, and adjust the radii to reflect what happens 232bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * in stroking: If the corner is sharp (no curvature), leave it alone, 233bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * otherwise we grow/shrink the radii by the amount of the inset. If a 234bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * given radius becomes negative, it is pinned to 0. 235bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * 236bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * It is valid for dst == this. 237bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org */ 23837071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org void outset(SkScalar dx, SkScalar dy, SkRRect* dst) const { 23937071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org this->inset(-dx, -dy, dst); 24037071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org } 24137071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org void outset(SkScalar dx, SkScalar dy) { 24237071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org this->inset(-dx, -dy, this); 24337071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org } 244f1f66c0c8623805fdb88f09c0d87cbdd1745e12bskia.committer@gmail.com 245fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org /** 246fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org * Translate the rrect by (dx, dy). 247fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org */ 248fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org void offset(SkScalar dx, SkScalar dy) { 249fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org fRect.offset(dx, dy); 250fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org } 25137071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org 25232c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com /** 25332c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com * Returns true if 'rect' is wholy inside the RR, and both 25432c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com * are not empty. 25532c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com */ 25632c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com bool contains(const SkRect& rect) const; 25732c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com 2585985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(void validate() const;) 2595985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2604ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com enum { 2614ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com kSizeInMemory = 12 * sizeof(SkScalar) 2624ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com }; 263306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 2644ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com /** 2654ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * Write the rrect into the specified buffer. This is guaranteed to always 2664ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * write kSizeInMemory bytes, and that value is guaranteed to always be 2674ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * a multiple of 4. Return kSizeInMemory. 2684ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com */ 2694faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org size_t writeToMemory(void* buffer) const; 2704ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2714ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com /** 2724faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * Reads the rrect from the specified buffer 2734faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 2744faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * If the specified buffer is large enough, this will read kSizeInMemory bytes, 2754faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * and that value is guaranteed to always be a multiple of 4. 2764faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 2774faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @param buffer Memory to read from 2784faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @param length Amount of memory available in the buffer 2794faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @return number of bytes read (must be a multiple of 4) or 2804faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 0 if there was not enough memory available 2814ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com */ 2824faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org size_t readFromMemory(const void* buffer, size_t length); 2834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 28420e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com /** 28520e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * Transform by the specified matrix, and put the result in dst. 28620e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * 28720e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * @param matrix SkMatrix specifying the transform. Must only contain 28820e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * scale and/or translate, or this call will fail. 28920e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * @param dst SkRRect to store the result. It is an error to use this, 29020e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * which would make this function no longer const. 29120e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * @return true on success, false on failure. If false, dst is unmodified. 29220e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com */ 29320e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com bool transform(const SkMatrix& matrix, SkRRect* dst) const; 29420e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com 295b6b02526438d6839481fb40ccf610d28f7652397bsalomon#ifdef SK_DEVELOPER 296b6b02526438d6839481fb40ccf610d28f7652397bsalomon /** 297b6b02526438d6839481fb40ccf610d28f7652397bsalomon * Prints the rrect using SkDebugf. This is intended for Skia development debugging. Don't 298b6b02526438d6839481fb40ccf610d28f7652397bsalomon * rely on the existence of this function or the formatting of its output. 299b6b02526438d6839481fb40ccf610d28f7652397bsalomon */ 300b6b02526438d6839481fb40ccf610d28f7652397bsalomon void dump() const; 301b6b02526438d6839481fb40ccf610d28f7652397bsalomon#endif 302b6b02526438d6839481fb40ccf610d28f7652397bsalomon 3035985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.comprivate: 3045985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkRect fRect; 3055985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com // Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[] 306c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com SkVector fRadii[4]; 3075985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com mutable Type fType; 3085985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com // TODO: add padding so we can use memcpy for flattening and not copy 3095985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com // uninitialized data 3105985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 3115985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void computeType() const; 31232c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com bool checkCornerContainment(SkScalar x, SkScalar y) const; 3134ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 3144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // to access fRadii directly 3154ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com friend class SkPath; 3165985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com}; 3175985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 318852030103e47fabc3c766122140920fa19e17775robertphillips@google.com#endif 319