12179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com/* 22179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Copyright 2012 Google Inc. 32179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * 42179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 52179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * found in the LICENSE file. 62179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com */ 72179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 82179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com#ifndef SkRRect_DEFINED 92179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com#define SkRRect_DEFINED 102179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 112179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com#include "SkRect.h" 122179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com#include "SkPoint.h" 132179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1440bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.comclass SkPath; 15c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.comclass SkMatrix; 1640bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com 172179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// Path forward: 182179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// core work 192179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// add validate method (all radii positive, all radii sums < rect size, etc.) 202179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// add contains(SkRect&) - for clip stack 212179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// add contains(SkRRect&) - for clip stack 222179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// add heart rect computation (max rect inside RR) 232179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// add 9patch rect computation 242179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// add growToInclude(SkPath&) 252179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// analysis 262179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// use growToInclude to fit skp round rects & generate stats (RRs vs. real paths) 272179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// check on # of rectorus's the RRs could handle 282179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// rendering work 298a428faa7234318fe74571ddb417e1cc43f7d193robertphillips@google.com// add entry points (clipRRect, drawRRect) - plumb down to SkBaseDevice 302179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// update SkPath.addRRect() to take an SkRRect - only use quads 312179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// -- alternatively add addRRectToPath here 322179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// add GM and bench 332179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// clipping opt 342179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// update SkClipStack to perform logic with RRs 352179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// further out 362179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// add RR rendering shader to Ganesh (akin to cicle drawing code) 372179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// - only for simple RRs 382179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com// detect and triangulate RRectorii rather than falling back to SW in Ganesh 39f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com// 402179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 412179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com/** \class SkRRect 422179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 43f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com The SkRRect class represents a rounded rect with a potentially different 44f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com radii for each corner. It does not have a constructor so must be 45f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com initialized with one of the initialization functions (e.g., setEmpty, 462179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com setRectRadii, etc.) 472179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 48f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com This class is intended to roughly match CSS' border-*-*-radius capabilities. 492179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com This means: 50f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com If either of a corner's radii are 0 the corner will be square. 512179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com Negative radii are not allowed (they are clamped to zero). 522179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com If the corner curves overlap they will be proportionally reduced to fit. 532179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com*/ 542179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.comclass SK_API SkRRect { 552179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.compublic: 56f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com /** 572179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Enum to capture the various possible subtypes of RR. Accessed 582179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * by type(). The subtypes become progressively less restrictive. 592179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com */ 602179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com enum Type { 619c8e9fb3f1b5aac7503ddfe267cdeac6f6ba6fc6tomhudson@google.com // !< Internal indicator that the sub type must be computed. 629c8e9fb3f1b5aac7503ddfe267cdeac6f6ba6fc6tomhudson@google.com kUnknown_Type = -1, 639c8e9fb3f1b5aac7503ddfe267cdeac6f6ba6fc6tomhudson@google.com 642179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com // !< The RR is empty 652179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com kEmpty_Type, 662179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 672179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com //!< The RR is actually a (non-empty) rect (i.e., at least one radius 682179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com //!< at each corner is zero) 69f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com kRect_Type, 702179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 71f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com //!< The RR is actually a (non-empty) oval (i.e., all x radii are equal 722179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com //!< and >= width/2 and all the y radii are equal and >= height/2 73f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com kOval_Type, 742179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 75f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com //!< The RR is non-empty and all the x radii are equal & all y radii 76f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com //!< are equal but it is not an oval (i.e., there are lines between 772179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com //!< the curves) nor a rect (i.e., both radii are non-zero) 78f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com kSimple_Type, 792179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 802179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com //!< A fully general (non-empty) RR. Some of the x and/or y radii are 812179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com //!< different from the others and there must be one corner where 822179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com //!< both radii are non-zero. 832179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com kComplex_Type, 842179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com }; 852179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 86f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com /** 872179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Returns the RR's sub type. 882179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com */ 8940bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com Type getType() const { 902179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkDEBUGCODE(this->validate();) 912179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 922179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com if (kUnknown_Type == fType) { 932179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com this->computeType(); 942179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 952179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkASSERT(kUnknown_Type != fType); 962179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com return fType; 972179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 982179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 9940bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com Type type() const { return this->getType(); } 10040bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com 10140bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com inline bool isEmpty() const { return kEmpty_Type == this->getType(); } 10240bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com inline bool isRect() const { return kRect_Type == this->getType(); } 10340bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com inline bool isOval() const { return kOval_Type == this->getType(); } 10440bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com inline bool isSimple() const { return kSimple_Type == this->getType(); } 10540bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com inline bool isComplex() const { return kComplex_Type == this->getType(); } 10640bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com 107703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org SkScalar width() const { return fRect.width(); } 108703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org SkScalar height() const { return fRect.height(); } 109703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org 110f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com /** 1112179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Set this RR to the empty rectangle (0,0,0,0) with 0 x & y radii. 1122179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com */ 113f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com void setEmpty() { 1142179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com fRect.setEmpty(); 1152179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com memset(fRadii, 0, sizeof(fRadii)); 1162179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com fType = kEmpty_Type; 1172179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1182179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkDEBUGCODE(this->validate();) 1192179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 1202179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 121f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com /** 1222179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Set this RR to match the supplied rect. All radii will be 0. 1232179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com */ 1242179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com void setRect(const SkRect& rect) { 1252179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com if (rect.isEmpty()) { 1262179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com this->setEmpty(); 1272179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com return; 1282179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 1292179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1302179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com fRect = rect; 1312179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com memset(fRadii, 0, sizeof(fRadii)); 1322179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com fType = kRect_Type; 1332179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1342179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkDEBUGCODE(this->validate();) 1352179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 1362179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 137f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com /** 1382179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Set this RR to match the supplied oval. All x radii will equal half the 1392179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * width and all y radii will equal half the height. 1402179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com */ 1412179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com void setOval(const SkRect& oval) { 1422179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com if (oval.isEmpty()) { 1432179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com this->setEmpty(); 1442179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com return; 1452179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 1462179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1472179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkScalar xRad = SkScalarHalf(oval.width()); 1482179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkScalar yRad = SkScalarHalf(oval.height()); 1492179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1502179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com fRect = oval; 1512179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com for (int i = 0; i < 4; ++i) { 1522179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com fRadii[i].set(xRad, yRad); 1532179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 1542179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com fType = kOval_Type; 1552179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1562179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkDEBUGCODE(this->validate();) 1572179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 1582179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 159f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com /** 1602179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Initialize the RR with the same radii for all four corners. 1612179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com */ 1622179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad); 1632179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 164f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com /** 1652179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com * Initialize the RR with potentially different radii for all four corners. 1662179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com */ 1672179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com void setRectRadii(const SkRect& rect, const SkVector radii[4]); 1682179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 169f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com // The radii are stored in UL, UR, LR, LL order. 1702179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com enum Corner { 1712179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com kUpperLeft_Corner, 1722179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com kUpperRight_Corner, 1732179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com kLowerRight_Corner, 1742179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com kLowerLeft_Corner 1752179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com }; 1762179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1772179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com const SkRect& rect() const { return fRect; } 1782179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com const SkVector& radii(Corner corner) const { return fRadii[corner]; } 17940bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com const SkRect& getBounds() const { return fRect; } 18040bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com 18140bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com /** 18240bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com * When a rrect is simple, all of its radii are equal. This returns one 18340bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com * of those radii. This call requires the rrect to be non-complex. 18440bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com */ 18540bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com const SkVector& getSimpleRadii() const { 18640bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com SkASSERT(!this->isComplex()); 18740bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com return fRadii[0]; 18840bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com } 1892179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1902179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com friend bool operator==(const SkRRect& a, const SkRRect& b) { 1912179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com return a.fRect == b.fRect && 1923f48c83fb549a9843334cd3f86a0429d5c62e74adjsollen@google.com SkScalarsEqual(a.fRadii[0].asScalars(), 1933f48c83fb549a9843334cd3f86a0429d5c62e74adjsollen@google.com b.fRadii[0].asScalars(), 8); 1942179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 1952179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 1962179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com friend bool operator!=(const SkRRect& a, const SkRRect& b) { 1972179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com return a.fRect != b.fRect || 1983f48c83fb549a9843334cd3f86a0429d5c62e74adjsollen@google.com !SkScalarsEqual(a.fRadii[0].asScalars(), 1993f48c83fb549a9843334cd3f86a0429d5c62e74adjsollen@google.com b.fRadii[0].asScalars(), 8); 2002179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com } 2012179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 2022179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com /** 203fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * Call inset on the bounds, and adjust the radii to reflect what happens 204fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * in stroking: If the corner is sharp (no curvature), leave it alone, 205fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * otherwise we grow/shrink the radii by the amount of the inset. If a 206fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * given radius becomes negative, it is pinned to 0. 207fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * 208fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * It is valid for dst == this. 209fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org */ 210703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org void inset(SkScalar dx, SkScalar dy, SkRRect* dst) const; 211fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org 212703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org void inset(SkScalar dx, SkScalar dy) { 213703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org this->inset(dx, dy, this); 214703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org } 215fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org 216fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org /** 217fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * Call outset on the bounds, and adjust the radii to reflect what happens 218fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * in stroking: If the corner is sharp (no curvature), leave it alone, 219fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * otherwise we grow/shrink the radii by the amount of the inset. If a 220fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * given radius becomes negative, it is pinned to 0. 221fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * 222fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org * It is valid for dst == this. 223fe41375efa844fe61802cf51ac4dd92ab8a411d1mike@reedtribe.org */ 224703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org void outset(SkScalar dx, SkScalar dy, SkRRect* dst) const { 225703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org this->inset(-dx, -dy, dst); 226703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org } 227703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org void outset(SkScalar dx, SkScalar dy) { 228703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org this->inset(-dx, -dy, this); 229703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org } 230703e6a0464633243ca12850fead31f61fd6b9a2bmike@reedtribe.org 231d6b76351fcc447f5ef8c883b6d6fbf7039f13c94robertphillips@google.com /** 232d6b76351fcc447f5ef8c883b6d6fbf7039f13c94robertphillips@google.com * Returns true if 'rect' is wholy inside the RR, and both 233d6b76351fcc447f5ef8c883b6d6fbf7039f13c94robertphillips@google.com * are not empty. 234d6b76351fcc447f5ef8c883b6d6fbf7039f13c94robertphillips@google.com */ 235d6b76351fcc447f5ef8c883b6d6fbf7039f13c94robertphillips@google.com bool contains(const SkRect& rect) const; 236d6b76351fcc447f5ef8c883b6d6fbf7039f13c94robertphillips@google.com 2372179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkDEBUGCODE(void validate() const;) 2382179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 23940bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com enum { 24040bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com kSizeInMemory = 12 * sizeof(SkScalar) 24140bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com }; 24208326dfc5f1f166488f6beaee3a3108c46b65bbfskia.committer@gmail.com 24340bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com /** 24440bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com * Write the rrect into the specified buffer. This is guaranteed to always 24540bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com * write kSizeInMemory bytes, and that value is guaranteed to always be 24640bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com * a multiple of 4. Return kSizeInMemory. 24740bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com */ 2483a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org size_t writeToMemory(void* buffer) const; 24940bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com 25040bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com /** 2513a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * Reads the rrect from the specified buffer 2523a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * 2533a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * If the specified buffer is large enough, this will read kSizeInMemory bytes, 2543a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * and that value is guaranteed to always be a multiple of 4. 2553a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * 2563a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * @param buffer Memory to read from 2573a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * @param length Amount of memory available in the buffer 2583a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * @return number of bytes read (must be a multiple of 4) or 2593a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org * 0 if there was not enough memory available 26040bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com */ 2613a7d93ce0ea5bbd43a8c998681bebfe3615b3480commit-bot@chromium.org size_t readFromMemory(const void* buffer, size_t length); 26240bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com 263c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com /** 264c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com * Transform by the specified matrix, and put the result in dst. 265c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com * 266c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com * @param matrix SkMatrix specifying the transform. Must only contain 267c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com * scale and/or translate, or this call will fail. 268c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com * @param dst SkRRect to store the result. It is an error to use this, 269c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com * which would make this function no longer const. 270c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com * @return true on success, false on failure. If false, dst is unmodified. 271c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com */ 272c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com bool transform(const SkMatrix& matrix, SkRRect* dst) const; 273c54761f13ae28def75a31eb0dc5963aba978e228scroggo@google.com 2742179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.comprivate: 2752179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com SkRect fRect; 2762179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com // Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[] 277f8f29177dd064bcfa4a7458e24434a807bca20b4skia.committer@gmail.com SkVector fRadii[4]; 2782179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com mutable Type fType; 2792179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com // TODO: add padding so we can use memcpy for flattening and not copy 2802179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com // uninitialized data 2812179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 2822179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com void computeType() const; 283d6b76351fcc447f5ef8c883b6d6fbf7039f13c94robertphillips@google.com bool checkCornerContainment(SkScalar x, SkScalar y) const; 28440bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com 28540bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com // to access fRadii directly 28640bb1e071dfd54678c0e9458bec337a1a38ed2d7reed@google.com friend class SkPath; 2872179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com}; 2882179b65d2ff87638ac83545bf3db1f59cf425457robertphillips@google.com 289d96f8bfd294adc44d3ee771150f2f3721d60855brobertphillips@google.com#endif 290