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.annotation.NonNull;
20 import android.graphics.Canvas;
21 import android.graphics.Paint;
22 import android.graphics.Path;
23 
24 import java.util.Objects;
25 
26 /**
27  * Creates geometric paths, utilizing the {@link android.graphics.Path} class.
28  * <p>
29  * The path can be drawn to a Canvas with its own draw() method,
30  * but more graphical control is available if you instead pass
31  * the PathShape to a {@link android.graphics.drawable.ShapeDrawable}.
32  */
33 public class PathShape extends Shape {
34     private final float mStdWidth;
35     private final float mStdHeight;
36 
37     private Path mPath;
38 
39     private float mScaleX; // cached from onResize
40     private float mScaleY; // cached from onResize
41 
42     /**
43      * PathShape constructor.
44      *
45      * @param path a Path that defines the geometric paths for this shape
46      * @param stdWidth the standard width for the shape. Any changes to the
47      *                 width with resize() will result in a width scaled based
48      *                 on the new width divided by this width.
49      * @param stdHeight the standard height for the shape. Any changes to the
50      *                  height with resize() will result in a height scaled based
51      *                  on the new height divided by this height.
52      */
PathShape(@onNull Path path, float stdWidth, float stdHeight)53     public PathShape(@NonNull Path path, float stdWidth, float stdHeight) {
54         mPath = path;
55         mStdWidth = stdWidth;
56         mStdHeight = stdHeight;
57     }
58 
59     @Override
draw(Canvas canvas, Paint paint)60     public void draw(Canvas canvas, Paint paint) {
61         canvas.save();
62         canvas.scale(mScaleX, mScaleY);
63         canvas.drawPath(mPath, paint);
64         canvas.restore();
65     }
66 
67     @Override
onResize(float width, float height)68     protected void onResize(float width, float height) {
69         mScaleX = width / mStdWidth;
70         mScaleY = height / mStdHeight;
71     }
72 
73     @Override
clone()74     public PathShape clone() throws CloneNotSupportedException {
75         final PathShape shape = (PathShape) super.clone();
76         shape.mPath = new Path(mPath);
77         return shape;
78     }
79 
80     @Override
equals(Object o)81     public boolean equals(Object o) {
82         if (this == o) {
83             return true;
84         }
85         if (o == null || getClass() != o.getClass()) {
86             return false;
87         }
88         if (!super.equals(o)) {
89             return false;
90         }
91         PathShape pathShape = (PathShape) o;
92         return Float.compare(pathShape.mStdWidth, mStdWidth) == 0
93             && Float.compare(pathShape.mStdHeight, mStdHeight) == 0
94             && Float.compare(pathShape.mScaleX, mScaleX) == 0
95             && Float.compare(pathShape.mScaleY, mScaleY) == 0
96             // Path does not have equals implementation but incase it gains one, use it here
97             && Objects.equals(mPath, pathShape.mPath);
98     }
99 
100     @Override
hashCode()101     public int hashCode() {
102         return Objects.hash(super.hashCode(), mStdWidth, mStdHeight, mPath, mScaleX, mScaleY);
103     }
104 }
105 
106