Outline.h revision b60d3e7856f74c72898b2cba553db0d2e2d1365d
1b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik/*
2b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * Copyright (C) 2014 The Android Open Source Project
3b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik *
4b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * Licensed under the Apache License, Version 2.0 (the "License");
5b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * you may not use this file except in compliance with the License.
6b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * You may obtain a copy of the License at
7b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik *
8b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik *      http://www.apache.org/licenses/LICENSE-2.0
9b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik *
10b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * Unless required by applicable law or agreed to in writing, software
11b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * distributed under the License is distributed on an "AS IS" BASIS,
12b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * See the License for the specific language governing permissions and
14b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik * limitations under the License.
15b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik */
16b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik#ifndef OUTLINE_H
17b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik#define OUTLINE_H
18b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
19b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik#include <SkPath.h>
20b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
21b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik#include "Rect.h"
22b60d3e7856f74c72898b2cba553db0d2e2d1365dChris Craik#include "utils/MathUtils.h"
23b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
24b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craiknamespace android {
25b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craiknamespace uirenderer {
26b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
27b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craikclass Outline {
28b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craikpublic:
29b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    Outline()
30b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik            : mShouldClip(false)
31b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik            , mType(kOutlineType_None)
3277b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik            , mRadius(0)
3377b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik            , mAlpha(0.0f) {}
34b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
3577b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik    void setRoundRect(int left, int top, int right, int bottom, float radius, float alpha) {
36b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mType = kOutlineType_RoundRect;
37b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mBounds.set(left, top, right, bottom);
38b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mRadius = radius;
39b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mPath.reset();
40b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom),
41b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik                radius, radius);
4277b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik        mAlpha = alpha;
43b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    }
44b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
4577b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik    void setConvexPath(const SkPath* outline, float alpha) {
46b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        if (!outline) {
47b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik            setEmpty();
48b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik            return;
49b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        }
50b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mType = kOutlineType_ConvexPath;
51b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mPath = *outline;
52b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mBounds.set(outline->getBounds());
5377b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik        mAlpha = alpha;
54b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    }
55b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
560645128b80621edee70f8cab4afb208fe0c26becChris Craik    void setEmpty() {
570645128b80621edee70f8cab4afb208fe0c26becChris Craik        mType = kOutlineType_Empty;
580645128b80621edee70f8cab4afb208fe0c26becChris Craik        mPath.reset();
5977b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik        mAlpha = 0.0f;
6061317325b7b4b4ffafd9400ab5966e8d7c67df2eChris Craik    }
6161317325b7b4b4ffafd9400ab5966e8d7c67df2eChris Craik
620645128b80621edee70f8cab4afb208fe0c26becChris Craik    void setNone() {
63b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mType = kOutlineType_None;
64b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mPath.reset();
6577b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik        mAlpha = 0.0f;
66b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    }
67b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
680645128b80621edee70f8cab4afb208fe0c26becChris Craik    bool isEmpty() const {
690645128b80621edee70f8cab4afb208fe0c26becChris Craik        return mType == kOutlineType_Empty;
700645128b80621edee70f8cab4afb208fe0c26becChris Craik    }
710645128b80621edee70f8cab4afb208fe0c26becChris Craik
7277b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik    float getAlpha() const {
7377b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik        return mAlpha;
7477b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik    }
7577b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik
76b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    void setShouldClip(bool clip) {
77b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        mShouldClip = clip;
78b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    }
79b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
80deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    bool getShouldClip() const {
81deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        return mShouldClip;
82deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    }
83deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
84b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    bool willClip() const {
85b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        // only round rect outlines can be used for clipping
86b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        return mShouldClip && (mType == kOutlineType_RoundRect);
87b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    }
88b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
89b60d3e7856f74c72898b2cba553db0d2e2d1365dChris Craik    bool willRoundRectClip() const {
90b60d3e7856f74c72898b2cba553db0d2e2d1365dChris Craik        // only round rect outlines can be used for clipping
91b60d3e7856f74c72898b2cba553db0d2e2d1365dChris Craik        return willClip() && MathUtils::isPositive(mRadius);
92b60d3e7856f74c72898b2cba553db0d2e2d1365dChris Craik    }
93b60d3e7856f74c72898b2cba553db0d2e2d1365dChris Craik
94deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    bool getAsRoundRect(Rect* outRect, float* outRadius) const {
95deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        if (mType == kOutlineType_RoundRect) {
96deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik            outRect->set(mBounds);
97deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik            *outRadius = mRadius;
98deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik            return true;
99deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        }
100deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik        return false;
101deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik    }
102deeda3d337aed1eee218b89a7aba5992ced371f0Chris Craik
103d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck    const SkPath* getPath() const {
104e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik        if (mType == kOutlineType_None || mType == kOutlineType_Empty) return nullptr;
105b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
106b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        return &mPath;
107b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    }
108b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
109b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craikprivate:
110b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    enum OutlineType {
111b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik        kOutlineType_None = 0,
1120645128b80621edee70f8cab4afb208fe0c26becChris Craik        kOutlineType_Empty = 1,
1130645128b80621edee70f8cab4afb208fe0c26becChris Craik        kOutlineType_ConvexPath = 2,
1140645128b80621edee70f8cab4afb208fe0c26becChris Craik        kOutlineType_RoundRect = 3
115b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    };
116b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
117b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    bool mShouldClip;
118b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    OutlineType mType;
119b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    Rect mBounds;
120b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    float mRadius;
12177b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik    float mAlpha;
122b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik    SkPath mPath;
123b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik};
124b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
125b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik} /* namespace uirenderer */
126b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik} /* namespace android */
127b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik
128b49f446c98096c4790a11d9b5bc83a4e585278c9Chris Craik#endif /* OUTLINE_H */
129