SkRRect.h revision 5a70bc7f3cd32aaccc137c7d650cea613baa2443
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 { 555985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com // !< The RR is empty 565985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kEmpty_Type, 575985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 585985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< The RR is actually a (non-empty) rect (i.e., at least one radius 595985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< at each corner is zero) 60c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com kRect_Type, 615985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 62c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com //!< The RR is actually a (non-empty) oval (i.e., all x radii are equal 635985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< and >= width/2 and all the y radii are equal and >= height/2 64c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com kOval_Type, 655985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 66c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com //!< The RR is non-empty and all the x radii are equal & all y radii 67c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com //!< are equal but it is not an oval (i.e., there are lines between 685985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< the curves) nor a rect (i.e., both radii are non-zero) 69c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com kSimple_Type, 705985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 71f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< The RR is non-empty and the two left x radii are equal, the two top 72f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< y radii are equal, and the same for the right and bottom but it is 73f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< neither an rect, oval, nor a simple RR. It is called "nine patch" 74f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< because the centers of the corner ellipses form an axis aligned 75f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< rect with edges that divide the RR into an 9 rectangular patches: 76f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org //!< an interior patch, four edge patches, and four corner patches. 77f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org kNinePatch_Type, 78f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org 795985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< A fully general (non-empty) RR. Some of the x and/or y radii are 805985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< different from the others and there must be one corner where 815985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com //!< both radii are non-zero. 825985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kComplex_Type, 835985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com }; 845985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 85c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 865985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Returns the RR's sub type. 875985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 884ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com Type getType() const { 895985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(this->validate();) 90727b8c1d1c0ba0634a97bff601e7af96bfd7daf8reed return static_cast<Type>(fType); 915985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 925985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com Type type() const { return this->getType(); } 944ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 954ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isEmpty() const { return kEmpty_Type == this->getType(); } 964ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isRect() const { return kRect_Type == this->getType(); } 974ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isOval() const { return kOval_Type == this->getType(); } 984ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isSimple() const { return kSimple_Type == this->getType(); } 9930c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips // TODO: should isSimpleCircular & isCircle take a tolerance? This could help 10030c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips // instances where the mapping to device space is noisy. 101c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org inline bool isSimpleCircular() const { 10230c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips return this->isSimple() && SkScalarNearlyEqual(fRadii[0].fX, fRadii[0].fY); 10330c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips } 10430c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips inline bool isCircle() const { 10530c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips return this->isOval() && SkScalarNearlyEqual(fRadii[0].fX, fRadii[0].fY); 106c2f7824436d05da6e8514d06a54773538aace028commit-bot@chromium.org } 107f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org inline bool isNinePatch() const { return kNinePatch_Type == this->getType(); } 1084ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com inline bool isComplex() const { return kComplex_Type == this->getType(); } 1094ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 110821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org bool allCornersCircular() const; 111821397018fdabea6b434ecb96f84fb5449c4025fcommit-bot@chromium.org 11237071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org SkScalar width() const { return fRect.width(); } 11337071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org SkScalar height() const { return fRect.height(); } 11437071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org 115c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 1165985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Set this RR to the empty rectangle (0,0,0,0) with 0 x & y radii. 1175985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 118c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com void setEmpty() { 1195985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fRect.setEmpty(); 1205985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com memset(fRadii, 0, sizeof(fRadii)); 1215985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fType = kEmpty_Type; 1225985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1235985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(this->validate();) 1245985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1255985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 126c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 1275985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Set this RR to match the supplied rect. All radii will be 0. 1285985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 1295985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void setRect(const SkRect& rect) { 13005302f8f24cf0254e1fa713fbfc766387505e511robertphillips fRect = rect; 13105302f8f24cf0254e1fa713fbfc766387505e511robertphillips fRect.sort(); 13205302f8f24cf0254e1fa713fbfc766387505e511robertphillips 13305302f8f24cf0254e1fa713fbfc766387505e511robertphillips if (fRect.isEmpty()) { 1345985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com this->setEmpty(); 1355985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return; 1365985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1375985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1385985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com memset(fRadii, 0, sizeof(fRadii)); 1395985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fType = kRect_Type; 1405985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1415985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(this->validate();) 1425985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1435985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 144021f631dc66da06dbe4aed21df2f27daecce9db7reed static SkRRect MakeRect(const SkRect& r) { 145021f631dc66da06dbe4aed21df2f27daecce9db7reed SkRRect rr; 146021f631dc66da06dbe4aed21df2f27daecce9db7reed rr.setRect(r); 147021f631dc66da06dbe4aed21df2f27daecce9db7reed return rr; 148021f631dc66da06dbe4aed21df2f27daecce9db7reed } 149021f631dc66da06dbe4aed21df2f27daecce9db7reed 15030c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips static SkRRect MakeOval(const SkRect& oval) { 15130c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips SkRRect rr; 15230c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips rr.setOval(oval); 15330c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips return rr; 15430c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips } 15530c4cae7d3a26252e7e45adf6e5722b34adf6848robertphillips 1564a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon static SkRRect MakeRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { 1574a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkRRect rr; 1584a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon rr.setRectXY(rect, xRad, yRad); 1594a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon return rr; 1604a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon } 1614a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 162c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 1635985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Set this RR to match the supplied oval. All x radii will equal half the 1645985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * width and all y radii will equal half the height. 1655985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 1665985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void setOval(const SkRect& oval) { 16705302f8f24cf0254e1fa713fbfc766387505e511robertphillips fRect = oval; 16805302f8f24cf0254e1fa713fbfc766387505e511robertphillips fRect.sort(); 16905302f8f24cf0254e1fa713fbfc766387505e511robertphillips 17005302f8f24cf0254e1fa713fbfc766387505e511robertphillips if (fRect.isEmpty()) { 1715985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com this->setEmpty(); 1725985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return; 1735985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1745985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 17505302f8f24cf0254e1fa713fbfc766387505e511robertphillips SkScalar xRad = SkScalarHalf(fRect.width()); 17605302f8f24cf0254e1fa713fbfc766387505e511robertphillips SkScalar yRad = SkScalarHalf(fRect.height()); 1775985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1785985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com for (int i = 0; i < 4; ++i) { 1795985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fRadii[i].set(xRad, yRad); 1805985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1815985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com fType = kOval_Type; 1825985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 1835985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(this->validate();) 1845985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 1855985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 186c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 1875985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Initialize the RR with the same radii for all four corners. 1885985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 1895985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad); 1905985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 191c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com /** 192f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org * Initialize the rr with one radius per-side. 193f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org */ 194f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org void setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad, 195f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org SkScalar rightRad, SkScalar bottomRad); 196f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org 197f338d7c860bf0bca82cac793069522311a3dbb1acommit-bot@chromium.org /** 1985985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com * Initialize the RR with potentially different radii for all four corners. 1995985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com */ 2005985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com void setRectRadii(const SkRect& rect, const SkVector radii[4]); 2015985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 202c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com // The radii are stored in UL, UR, LR, LL order. 2035985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com enum Corner { 2045985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kUpperLeft_Corner, 2055985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kUpperRight_Corner, 2065985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kLowerRight_Corner, 2075985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com kLowerLeft_Corner 2085985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com }; 2095985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2105985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com const SkRect& rect() const { return fRect; } 2115985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com const SkVector& radii(Corner corner) const { return fRadii[corner]; } 2124ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com const SkRect& getBounds() const { return fRect; } 2134ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2144ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com /** 2154ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * When a rrect is simple, all of its radii are equal. This returns one 2164ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * of those radii. This call requires the rrect to be non-complex. 2174ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com */ 2184ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com const SkVector& getSimpleRadii() const { 2194ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com SkASSERT(!this->isComplex()); 2204ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com return fRadii[0]; 2214ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com } 2225985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2235985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com friend bool operator==(const SkRRect& a, const SkRRect& b) { 2245985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return a.fRect == b.fRect && 2254bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com SkScalarsEqual(a.fRadii[0].asScalars(), 2264bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com b.fRadii[0].asScalars(), 8); 2275985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 2285985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2295985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com friend bool operator!=(const SkRRect& a, const SkRRect& b) { 2305985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com return a.fRect != b.fRect || 2314bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com !SkScalarsEqual(a.fRadii[0].asScalars(), 2324bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com b.fRadii[0].asScalars(), 8); 2335985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com } 2345985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2355985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com /** 236bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * Call inset on the bounds, and adjust the radii to reflect what happens 237bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * in stroking: If the corner is sharp (no curvature), leave it alone, 238bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * otherwise we grow/shrink the radii by the amount of the inset. If a 239bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * given radius becomes negative, it is pinned to 0. 240bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * 241bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * It is valid for dst == this. 242bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org */ 24337071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org void inset(SkScalar dx, SkScalar dy, SkRRect* dst) const; 244bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org 24537071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org void inset(SkScalar dx, SkScalar dy) { 24637071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org this->inset(dx, dy, this); 24737071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org } 248bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org 249bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org /** 250bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * Call outset on the bounds, and adjust the radii to reflect what happens 251bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * in stroking: If the corner is sharp (no curvature), leave it alone, 252bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * otherwise we grow/shrink the radii by the amount of the inset. If a 253bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * given radius becomes negative, it is pinned to 0. 254bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * 255bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org * It is valid for dst == this. 256bcbef579d02e255b9a29b5db2d6804f4bfc76d1cmike@reedtribe.org */ 25737071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org void outset(SkScalar dx, SkScalar dy, SkRRect* dst) const { 25837071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org this->inset(-dx, -dy, dst); 25937071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org } 26037071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org void outset(SkScalar dx, SkScalar dy) { 26137071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org this->inset(-dx, -dy, this); 26237071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org } 263f1f66c0c8623805fdb88f09c0d87cbdd1745e12bskia.committer@gmail.com 264fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org /** 265fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org * Translate the rrect by (dx, dy). 266fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org */ 267fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org void offset(SkScalar dx, SkScalar dy) { 268fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org fRect.offset(dx, dy); 269fbde87f53d659ae2bd616751e466c887b0f3bee5commit-bot@chromium.org } 27037071640f6bdcb1bfb193f85b9ca615b29679425mike@reedtribe.org 27132c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com /** 27232c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com * Returns true if 'rect' is wholy inside the RR, and both 27332c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com * are not empty. 27432c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com */ 27532c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com bool contains(const SkRect& rect) const; 27632c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com 2775985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkDEBUGCODE(void validate() const;) 2785985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 2794ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com enum { 2804ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com kSizeInMemory = 12 * sizeof(SkScalar) 2814ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com }; 282306ab9d5de38f2a547fd1d69aedbe69b5c6617ccskia.committer@gmail.com 2834ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com /** 2844ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * Write the rrect into the specified buffer. This is guaranteed to always 2854ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * write kSizeInMemory bytes, and that value is guaranteed to always be 2864ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com * a multiple of 4. Return kSizeInMemory. 2874ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com */ 2884faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org size_t writeToMemory(void* buffer) const; 2894ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 2904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com /** 2914faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * Reads the rrect from the specified buffer 2924faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 2934faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * If the specified buffer is large enough, this will read kSizeInMemory bytes, 2944faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * and that value is guaranteed to always be a multiple of 4. 2954faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 2964faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @param buffer Memory to read from 2974faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @param length Amount of memory available in the buffer 2984faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @return number of bytes read (must be a multiple of 4) or 2994faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 0 if there was not enough memory available 3004ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com */ 3014faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org size_t readFromMemory(const void* buffer, size_t length); 3024ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 30320e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com /** 30420e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * Transform by the specified matrix, and put the result in dst. 30520e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * 30620e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * @param matrix SkMatrix specifying the transform. Must only contain 30720e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * scale and/or translate, or this call will fail. 30820e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * @param dst SkRRect to store the result. It is an error to use this, 30920e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * which would make this function no longer const. 31020e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com * @return true on success, false on failure. If false, dst is unmodified. 31120e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com */ 31220e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com bool transform(const SkMatrix& matrix, SkRRect* dst) const; 31320e3cd2c9fbc049eae8bcedc591c2cc8d4bed656scroggo@google.com 314e05fed0d6339c63c8cceff74af0b8d120c07e54creed void dump(bool asHex) const; 315e05fed0d6339c63c8cceff74af0b8d120c07e54creed void dump() const { this->dump(false); } 316e05fed0d6339c63c8cceff74af0b8d120c07e54creed void dumpHex() const { this->dump(true); } 317b6b02526438d6839481fb40ccf610d28f7652397bsalomon 3185985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.comprivate: 3195985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com SkRect fRect; 3205985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com // Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[] 321c3d7d90973528527131c72549b10c2a21300e0acskia.committer@gmail.com SkVector fRadii[4]; 322727b8c1d1c0ba0634a97bff601e7af96bfd7daf8reed // use an explicitly sized type so we're sure the class is dense (no uninitialized bytes) 3238aacf2085673f6302a43d590d4d2890789b87192mtklein int32_t fType; 3245985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com // TODO: add padding so we can use memcpy for flattening and not copy 3255985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com // uninitialized data 3265985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 3278aacf2085673f6302a43d590d4d2890789b87192mtklein void computeType(); 32832c1b66a2c4f26935ba59f3afe3e81600fade78drobertphillips@google.com bool checkCornerContainment(SkScalar x, SkScalar y) const; 3295a70bc7f3cd32aaccc137c7d650cea613baa2443caryclark void scaleRadii(); 3304ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 3314ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com // to access fRadii directly 3324ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com friend class SkPath; 3335985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com}; 3345985e7c4d13b04d6b819bfff3df44f1dd3eb35b8robertphillips@google.com 335852030103e47fabc3c766122140920fa19e17775robertphillips@google.com#endif 336