19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.graphics.drawable.shapes;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Path;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.RectF;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a rounded-corner rectangle. Optionally, an inset (rounded) rectangle
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can be included (to make a sort of "O" shape).
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The rounded rectangle can be drawn to a Canvas with its own draw() method,
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but more graphical control is available if you instead pass
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the RoundRectShape to a {@link android.graphics.drawable.ShapeDrawable}.
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RoundRectShape extends RectShape {
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private float[] mOuterRadii;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private RectF   mInset;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private float[] mInnerRadii;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private RectF mInnerRect;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Path  mPath;    // this is what we actually draw
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * RoundRectShape constructor.
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Specifies an outer (round)rect and an optional inner (round)rect.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param outerRadii An array of 8 radius values, for the outer roundrect.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   The first two floats are for the
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   top-left corner (remaining pairs correspond clockwise).
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   For no rounded corners on the outer rectangle,
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   pass null.
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param inset      A RectF that specifies the distance from the inner
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   rect to each side of the outer rect.
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   For no inner, pass null.
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param innerRadii An array of 8 radius values, for the inner roundrect.
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   The first two floats are for the
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   top-left corner (remaining pairs correspond clockwise).
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   For no rounded corners on the inner rectangle,
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   pass null.
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *                   If inset parameter is null, this parameter is ignored.
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RoundRectShape(float[] outerRadii, RectF inset,
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          float[] innerRadii) {
609e044aed219adf52e27629d36f8ff7d670700a52Romain Guy        if (outerRadii != null && outerRadii.length < 8) {
619e044aed219adf52e27629d36f8ff7d670700a52Romain Guy            throw new ArrayIndexOutOfBoundsException("outer radii must have >= 8 values");
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (innerRadii != null && innerRadii.length < 8) {
649e044aed219adf52e27629d36f8ff7d670700a52Romain Guy            throw new ArrayIndexOutOfBoundsException("inner radii must have >= 8 values");
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOuterRadii = outerRadii;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInset = inset;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInnerRadii = innerRadii;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (inset != null) {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInnerRect = new RectF();
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPath = new Path();
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas canvas, Paint paint) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        canvas.drawPath(mPath, paint);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onResize(float w, float h) {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onResize(w, h);
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RectF r = rect();
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPath.reset();
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mOuterRadii != null) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPath.addRoundRect(r, mOuterRadii, Path.Direction.CW);
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mPath.addRect(r, Path.Direction.CW);
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInnerRect != null) {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInnerRect.set(r.left + mInset.left, r.top + mInset.top,
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                           r.right - mInset.right, r.bottom - mInset.bottom);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInnerRect.width() < w && mInnerRect.height() < h) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mInnerRadii != null) {
989e044aed219adf52e27629d36f8ff7d670700a52Romain Guy                    mPath.addRoundRect(mInnerRect, mInnerRadii, Path.Direction.CCW);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mPath.addRect(mInnerRect, Path.Direction.CCW);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public RoundRectShape clone() throws CloneNotSupportedException {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        RoundRectShape shape = (RoundRectShape) super.clone();
1099e044aed219adf52e27629d36f8ff7d670700a52Romain Guy        shape.mOuterRadii = mOuterRadii != null ? mOuterRadii.clone() : null;
1109e044aed219adf52e27629d36f8ff7d670700a52Romain Guy        shape.mInnerRadii = mInnerRadii != null ? mInnerRadii.clone() : null;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        shape.mInset = new RectF(mInset);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        shape.mInnerRect = new RectF(mInnerRect);
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        shape.mPath = new Path(mPath);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return shape;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
117