RoundRectShape.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
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
17package android.graphics.drawable.shapes;
18
19import android.graphics.Canvas;
20import android.graphics.Paint;
21import android.graphics.Path;
22import 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 */
31public 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     */
58    public RoundRectShape(float[] outerRadii, RectF inset,
59                          float[] innerRadii) {
60        if (outerRadii.length < 8) {
61            throw new ArrayIndexOutOfBoundsException(
62                                        "outer radii must have >= 8 values");
63        }
64        if (innerRadii != null && innerRadii.length < 8) {
65            throw new ArrayIndexOutOfBoundsException(
66                                        "inner radii must have >= 8 values");
67        }
68        mOuterRadii = outerRadii;
69        mInset = inset;
70        mInnerRadii = innerRadii;
71
72        if (inset != null) {
73            mInnerRect = new RectF();
74        }
75        mPath = new Path();
76    }
77
78    @Override
79    public void draw(Canvas canvas, Paint paint) {
80        canvas.drawPath(mPath, paint);
81    }
82
83    @Override
84    protected void onResize(float w, float h) {
85        super.onResize(w, h);
86
87        RectF r = rect();
88        mPath.reset();
89
90        if (mOuterRadii != null) {
91            mPath.addRoundRect(r, mOuterRadii, Path.Direction.CW);
92        } else {
93            mPath.addRect(r, Path.Direction.CW);
94        }
95        if (mInnerRect != null) {
96            mInnerRect.set(r.left + mInset.left, r.top + mInset.top,
97                           r.right - mInset.right, r.bottom - mInset.bottom);
98            if (mInnerRect.width() < w && mInnerRect.height() < h) {
99                if (mInnerRadii != null) {
100                    mPath.addRoundRect(mInnerRect, mInnerRadii,
101                                       Path.Direction.CCW);
102                } else {
103                    mPath.addRect(mInnerRect, Path.Direction.CCW);
104                }
105            }
106        }
107    }
108}
109