• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.graphics.drawable.shapes;
18 
19 import android.graphics.Canvas;
20 import android.graphics.Paint;
21 import android.graphics.Path;
22 import android.graphics.RectF;
23 
24 /**
25  * Creates a rounded-corner rectangle. Optionally, an inset (rounded) rectangle
26  * can be included (to make a sort of "O" shape).
27  * The rounded rectangle can be drawn to a Canvas with its own draw() method,
28  * but more graphical control is available if you instead pass
29  * the RoundRectShape to a {@link android.graphics.drawable.ShapeDrawable}.
30  */
31 public class RoundRectShape extends RectShape {
32     private float[] mOuterRadii;
33     private RectF   mInset;
34     private float[] mInnerRadii;
35 
36     private RectF mInnerRect;
37     private Path  mPath;    // this is what we actually draw
38 
39     /**
40      * RoundRectShape constructor.
41      * Specifies an outer (round)rect and an optional inner (round)rect.
42      *
43      * @param outerRadii An array of 8 radius values, for the outer roundrect.
44      *                   The first two floats are for the
45      *                   top-left corner (remaining pairs correspond clockwise).
46      *                   For no rounded corners on the outer rectangle,
47      *                   pass null.
48      * @param inset      A RectF that specifies the distance from the inner
49      *                   rect to each side of the outer rect.
50      *                   For no inner, pass null.
51      * @param innerRadii An array of 8 radius values, for the inner roundrect.
52      *                   The first two floats are for the
53      *                   top-left corner (remaining pairs correspond clockwise).
54      *                   For no rounded corners on the inner rectangle,
55      *                   pass null.
56      *                   If inset parameter is null, this parameter is ignored.
57      */
RoundRectShape(float[] outerRadii, RectF inset, float[] innerRadii)58     public RoundRectShape(float[] outerRadii, RectF inset,
59                           float[] innerRadii) {
60         if (outerRadii != null && outerRadii.length < 8) {
61             throw new ArrayIndexOutOfBoundsException("outer radii must have >= 8 values");
62         }
63         if (innerRadii != null && innerRadii.length < 8) {
64             throw new ArrayIndexOutOfBoundsException("inner radii must have >= 8 values");
65         }
66         mOuterRadii = outerRadii;
67         mInset = inset;
68         mInnerRadii = innerRadii;
69 
70         if (inset != null) {
71             mInnerRect = new RectF();
72         }
73         mPath = new Path();
74     }
75 
76     @Override
draw(Canvas canvas, Paint paint)77     public void draw(Canvas canvas, Paint paint) {
78         canvas.drawPath(mPath, paint);
79     }
80 
81     @Override
onResize(float w, float h)82     protected void onResize(float w, float h) {
83         super.onResize(w, h);
84 
85         RectF r = rect();
86         mPath.reset();
87 
88         if (mOuterRadii != null) {
89             mPath.addRoundRect(r, mOuterRadii, Path.Direction.CW);
90         } else {
91             mPath.addRect(r, Path.Direction.CW);
92         }
93         if (mInnerRect != null) {
94             mInnerRect.set(r.left + mInset.left, r.top + mInset.top,
95                            r.right - mInset.right, r.bottom - mInset.bottom);
96             if (mInnerRect.width() < w && mInnerRect.height() < h) {
97                 if (mInnerRadii != null) {
98                     mPath.addRoundRect(mInnerRect, mInnerRadii, Path.Direction.CCW);
99                 } else {
100                     mPath.addRect(mInnerRect, Path.Direction.CCW);
101                 }
102             }
103         }
104     }
105 
106     @Override
clone()107     public RoundRectShape clone() throws CloneNotSupportedException {
108         RoundRectShape shape = (RoundRectShape) super.clone();
109         shape.mOuterRadii = mOuterRadii != null ? mOuterRadii.clone() : null;
110         shape.mInnerRadii = mInnerRadii != null ? mInnerRadii.clone() : null;
111         shape.mInset = new RectF(mInset);
112         shape.mInnerRect = new RectF(mInnerRect);
113         shape.mPath = new Path(mPath);
114         return shape;
115     }
116 }
117