1 /*
2  * Copyright (C) 2014 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 #ifndef OUTLINE_H
17 #define OUTLINE_H
18 
19 #include <SkPath.h>
20 
21 #include "Rect.h"
22 #include "utils/MathUtils.h"
23 
24 namespace android {
25 namespace uirenderer {
26 
27 class Outline {
28 public:
Outline()29     Outline()
30             : mShouldClip(false)
31             , mType(kOutlineType_None)
32             , mRadius(0)
33             , mAlpha(0.0f) {}
34 
setRoundRect(int left,int top,int right,int bottom,float radius,float alpha)35     void setRoundRect(int left, int top, int right, int bottom, float radius, float alpha) {
36         mType = kOutlineType_RoundRect;
37         mBounds.set(left, top, right, bottom);
38         mRadius = radius;
39         mPath.reset();
40         mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom),
41                 radius, radius);
42         mAlpha = alpha;
43     }
44 
setConvexPath(const SkPath * outline,float alpha)45     void setConvexPath(const SkPath* outline, float alpha) {
46         if (!outline) {
47             setEmpty();
48             return;
49         }
50         mType = kOutlineType_ConvexPath;
51         mPath = *outline;
52         mBounds.set(outline->getBounds());
53         mAlpha = alpha;
54     }
55 
setEmpty()56     void setEmpty() {
57         mType = kOutlineType_Empty;
58         mPath.reset();
59         mAlpha = 0.0f;
60     }
61 
setNone()62     void setNone() {
63         mType = kOutlineType_None;
64         mPath.reset();
65         mAlpha = 0.0f;
66     }
67 
isEmpty()68     bool isEmpty() const {
69         return mType == kOutlineType_Empty;
70     }
71 
getAlpha()72     float getAlpha() const {
73         return mAlpha;
74     }
75 
setShouldClip(bool clip)76     void setShouldClip(bool clip) {
77         mShouldClip = clip;
78     }
79 
getShouldClip()80     bool getShouldClip() const {
81         return mShouldClip;
82     }
83 
willClip()84     bool willClip() const {
85         // only round rect outlines can be used for clipping
86         return mShouldClip && (mType == kOutlineType_RoundRect);
87     }
88 
willRoundRectClip()89     bool willRoundRectClip() const {
90         // only round rect outlines can be used for clipping
91         return willClip() && MathUtils::isPositive(mRadius);
92     }
93 
getAsRoundRect(Rect * outRect,float * outRadius)94     bool getAsRoundRect(Rect* outRect, float* outRadius) const {
95         if (mType == kOutlineType_RoundRect) {
96             outRect->set(mBounds);
97             *outRadius = mRadius;
98             return true;
99         }
100         return false;
101     }
102 
getPath()103     const SkPath* getPath() const {
104         if (mType == kOutlineType_None || mType == kOutlineType_Empty) return nullptr;
105 
106         return &mPath;
107     }
108 
109 private:
110     enum OutlineType {
111         kOutlineType_None = 0,
112         kOutlineType_Empty = 1,
113         kOutlineType_ConvexPath = 2,
114         kOutlineType_RoundRect = 3
115     };
116 
117     bool mShouldClip;
118     OutlineType mType;
119     Rect mBounds;
120     float mRadius;
121     float mAlpha;
122     SkPath mPath;
123 };
124 
125 } /* namespace uirenderer */
126 } /* namespace android */
127 
128 #endif /* OUTLINE_H */
129