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
24namespace android {
25namespace uirenderer {
26
27class Outline {
28public:
29    Outline()
30            : mShouldClip(false)
31            , mType(kOutlineType_None)
32            , mRadius(0)
33            , mAlpha(0.0f) {}
34
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
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
56    void setEmpty() {
57        mType = kOutlineType_Empty;
58        mPath.reset();
59        mAlpha = 0.0f;
60    }
61
62    void setNone() {
63        mType = kOutlineType_None;
64        mPath.reset();
65        mAlpha = 0.0f;
66    }
67
68    bool isEmpty() const {
69        return mType == kOutlineType_Empty;
70    }
71
72    float getAlpha() const {
73        return mAlpha;
74    }
75
76    void setShouldClip(bool clip) {
77        mShouldClip = clip;
78    }
79
80    bool getShouldClip() const {
81        return mShouldClip;
82    }
83
84    bool willClip() const {
85        // only round rect outlines can be used for clipping
86        return mShouldClip && (mType == kOutlineType_RoundRect);
87    }
88
89    bool willRoundRectClip() const {
90        // only round rect outlines can be used for clipping
91        return willClip() && MathUtils::isPositive(mRadius);
92    }
93
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
103    const SkPath* getPath() const {
104        if (mType == kOutlineType_None || mType == kOutlineType_Empty) return nullptr;
105
106        return &mPath;
107    }
108
109private:
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