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