xref: /aosp_15_r20/frameworks/base/libs/hwui/Outline.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker #ifndef OUTLINE_H
17*d57664e9SAndroid Build Coastguard Worker #define OUTLINE_H
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include <SkPath.h>
20*d57664e9SAndroid Build Coastguard Worker 
21*d57664e9SAndroid Build Coastguard Worker #include "Rect.h"
22*d57664e9SAndroid Build Coastguard Worker #include "utils/MathUtils.h"
23*d57664e9SAndroid Build Coastguard Worker 
24*d57664e9SAndroid Build Coastguard Worker namespace android {
25*d57664e9SAndroid Build Coastguard Worker namespace uirenderer {
26*d57664e9SAndroid Build Coastguard Worker 
27*d57664e9SAndroid Build Coastguard Worker class Outline {
28*d57664e9SAndroid Build Coastguard Worker public:
29*d57664e9SAndroid Build Coastguard Worker     enum class Type { None = 0, Empty = 1, Path = 2, RoundRect = 3 };
30*d57664e9SAndroid Build Coastguard Worker 
Outline()31*d57664e9SAndroid Build Coastguard Worker     Outline() : mShouldClip(false), mType(Type::None), mRadius(0), mAlpha(0.0f) {}
32*d57664e9SAndroid Build Coastguard Worker 
setRoundRect(int left,int top,int right,int bottom,float radius,float alpha)33*d57664e9SAndroid Build Coastguard Worker     void setRoundRect(int left, int top, int right, int bottom, float radius, float alpha) {
34*d57664e9SAndroid Build Coastguard Worker         mAlpha = alpha;
35*d57664e9SAndroid Build Coastguard Worker         if (mType == Type::RoundRect && left == mBounds.left && right == mBounds.right &&
36*d57664e9SAndroid Build Coastguard Worker             top == mBounds.top && bottom == mBounds.bottom && radius == mRadius) {
37*d57664e9SAndroid Build Coastguard Worker             // nothing to change, don't do any work
38*d57664e9SAndroid Build Coastguard Worker             return;
39*d57664e9SAndroid Build Coastguard Worker         }
40*d57664e9SAndroid Build Coastguard Worker 
41*d57664e9SAndroid Build Coastguard Worker         mType = Type::RoundRect;
42*d57664e9SAndroid Build Coastguard Worker         mBounds.set(left, top, right, bottom);
43*d57664e9SAndroid Build Coastguard Worker         mRadius = radius;
44*d57664e9SAndroid Build Coastguard Worker 
45*d57664e9SAndroid Build Coastguard Worker         // Reuse memory if previous outline was the same shape (rect or round rect).
46*d57664e9SAndroid Build Coastguard Worker         if (mPath.countVerbs() > 10) {
47*d57664e9SAndroid Build Coastguard Worker             mPath.reset();
48*d57664e9SAndroid Build Coastguard Worker         } else {
49*d57664e9SAndroid Build Coastguard Worker             mPath.rewind();
50*d57664e9SAndroid Build Coastguard Worker         }
51*d57664e9SAndroid Build Coastguard Worker 
52*d57664e9SAndroid Build Coastguard Worker         // update mPath to reflect new outline
53*d57664e9SAndroid Build Coastguard Worker         if (MathUtils::isPositive(radius)) {
54*d57664e9SAndroid Build Coastguard Worker             mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom), radius, radius);
55*d57664e9SAndroid Build Coastguard Worker         } else {
56*d57664e9SAndroid Build Coastguard Worker             mPath.addRect(left, top, right, bottom);
57*d57664e9SAndroid Build Coastguard Worker         }
58*d57664e9SAndroid Build Coastguard Worker     }
59*d57664e9SAndroid Build Coastguard Worker 
setPath(const SkPath * outline,float alpha)60*d57664e9SAndroid Build Coastguard Worker     void setPath(const SkPath* outline, float alpha) {
61*d57664e9SAndroid Build Coastguard Worker         if (!outline) {
62*d57664e9SAndroid Build Coastguard Worker             setEmpty();
63*d57664e9SAndroid Build Coastguard Worker             return;
64*d57664e9SAndroid Build Coastguard Worker         }
65*d57664e9SAndroid Build Coastguard Worker         mType = Type::Path;
66*d57664e9SAndroid Build Coastguard Worker         mPath = *outline;
67*d57664e9SAndroid Build Coastguard Worker         mBounds.set(outline->getBounds());
68*d57664e9SAndroid Build Coastguard Worker         mAlpha = alpha;
69*d57664e9SAndroid Build Coastguard Worker     }
70*d57664e9SAndroid Build Coastguard Worker 
setEmpty()71*d57664e9SAndroid Build Coastguard Worker     void setEmpty() {
72*d57664e9SAndroid Build Coastguard Worker         mType = Type::Empty;
73*d57664e9SAndroid Build Coastguard Worker         mPath.reset();
74*d57664e9SAndroid Build Coastguard Worker         mAlpha = 0.0f;
75*d57664e9SAndroid Build Coastguard Worker     }
76*d57664e9SAndroid Build Coastguard Worker 
setNone()77*d57664e9SAndroid Build Coastguard Worker     void setNone() {
78*d57664e9SAndroid Build Coastguard Worker         mType = Type::None;
79*d57664e9SAndroid Build Coastguard Worker         mPath.reset();
80*d57664e9SAndroid Build Coastguard Worker         mAlpha = 0.0f;
81*d57664e9SAndroid Build Coastguard Worker     }
82*d57664e9SAndroid Build Coastguard Worker 
isEmpty()83*d57664e9SAndroid Build Coastguard Worker     bool isEmpty() const { return mType == Type::Empty; }
84*d57664e9SAndroid Build Coastguard Worker 
getAlpha()85*d57664e9SAndroid Build Coastguard Worker     float getAlpha() const { return mAlpha; }
86*d57664e9SAndroid Build Coastguard Worker 
setShouldClip(bool clip)87*d57664e9SAndroid Build Coastguard Worker     void setShouldClip(bool clip) { mShouldClip = clip; }
88*d57664e9SAndroid Build Coastguard Worker 
getShouldClip()89*d57664e9SAndroid Build Coastguard Worker     bool getShouldClip() const { return mShouldClip; }
90*d57664e9SAndroid Build Coastguard Worker 
willClip()91*d57664e9SAndroid Build Coastguard Worker     bool willClip() const { return mShouldClip; }
92*d57664e9SAndroid Build Coastguard Worker 
willComplexClip()93*d57664e9SAndroid Build Coastguard Worker     bool willComplexClip() const {
94*d57664e9SAndroid Build Coastguard Worker         return mShouldClip && (mType != Type::RoundRect || MathUtils::isPositive(mRadius));
95*d57664e9SAndroid Build Coastguard Worker     }
96*d57664e9SAndroid Build Coastguard Worker 
getAsRoundRect(Rect * outRect,float * outRadius)97*d57664e9SAndroid Build Coastguard Worker     bool getAsRoundRect(Rect* outRect, float* outRadius) const {
98*d57664e9SAndroid Build Coastguard Worker         if (mType == Type::RoundRect) {
99*d57664e9SAndroid Build Coastguard Worker             outRect->set(mBounds);
100*d57664e9SAndroid Build Coastguard Worker             *outRadius = mRadius;
101*d57664e9SAndroid Build Coastguard Worker             return true;
102*d57664e9SAndroid Build Coastguard Worker         }
103*d57664e9SAndroid Build Coastguard Worker         return false;
104*d57664e9SAndroid Build Coastguard Worker     }
105*d57664e9SAndroid Build Coastguard Worker 
getPath()106*d57664e9SAndroid Build Coastguard Worker     const SkPath* getPath() const {
107*d57664e9SAndroid Build Coastguard Worker         if (mType == Type::None || mType == Type::Empty) return nullptr;
108*d57664e9SAndroid Build Coastguard Worker 
109*d57664e9SAndroid Build Coastguard Worker         return &mPath;
110*d57664e9SAndroid Build Coastguard Worker     }
111*d57664e9SAndroid Build Coastguard Worker 
getType()112*d57664e9SAndroid Build Coastguard Worker     Type getType() const { return mType; }
113*d57664e9SAndroid Build Coastguard Worker 
getBounds()114*d57664e9SAndroid Build Coastguard Worker     const Rect& getBounds() const { return mBounds; }
115*d57664e9SAndroid Build Coastguard Worker 
getRadius()116*d57664e9SAndroid Build Coastguard Worker     float getRadius() const { return mRadius; }
117*d57664e9SAndroid Build Coastguard Worker 
118*d57664e9SAndroid Build Coastguard Worker private:
119*d57664e9SAndroid Build Coastguard Worker     bool mShouldClip;
120*d57664e9SAndroid Build Coastguard Worker     Type mType;
121*d57664e9SAndroid Build Coastguard Worker     Rect mBounds;
122*d57664e9SAndroid Build Coastguard Worker     float mRadius;
123*d57664e9SAndroid Build Coastguard Worker     float mAlpha;
124*d57664e9SAndroid Build Coastguard Worker     SkPath mPath;
125*d57664e9SAndroid Build Coastguard Worker };
126*d57664e9SAndroid Build Coastguard Worker 
127*d57664e9SAndroid Build Coastguard Worker } /* namespace uirenderer */
128*d57664e9SAndroid Build Coastguard Worker } /* namespace android */
129*d57664e9SAndroid Build Coastguard Worker 
130*d57664e9SAndroid Build Coastguard Worker #endif /* OUTLINE_H */
131