blob: 922ff7caecb828281c509e5a280cbb304faeefb5 [file] [log] [blame]
Chris Craikb49f4462014-03-20 12:44:20 -07001/*
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"
Chris Craikb60d3e72015-06-25 17:15:16 -070022#include "utils/MathUtils.h"
Chris Craikb49f4462014-03-20 12:44:20 -070023
24namespace android {
25namespace uirenderer {
26
27class Outline {
28public:
John Recke248bd12015-08-05 13:53:53 -070029 enum class Type {
30 None = 0,
31 Empty = 1,
32 ConvexPath = 2,
33 RoundRect = 3
34 };
35
Chris Craikb49f4462014-03-20 12:44:20 -070036 Outline()
37 : mShouldClip(false)
Chris Craikb9ce116d2015-08-20 15:14:06 -070038 , mType(Type::None)
Chris Craik77b5cad2014-07-30 18:23:07 -070039 , mRadius(0)
40 , mAlpha(0.0f) {}
Chris Craikb49f4462014-03-20 12:44:20 -070041
Chris Craik77b5cad2014-07-30 18:23:07 -070042 void setRoundRect(int left, int top, int right, int bottom, float radius, float alpha) {
Chris Craik40de9f22015-07-29 12:51:41 -070043 mAlpha = alpha;
Chris Craikb9ce116d2015-08-20 15:14:06 -070044 if (mType == Type::RoundRect
Chris Craik40de9f22015-07-29 12:51:41 -070045 && left == mBounds.left
46 && right == mBounds.right
47 && top == mBounds.top
48 && bottom == mBounds.bottom
49 && radius == mRadius) {
50 // nothing to change, don't do any work
51 return;
52 }
53
Chris Craikb9ce116d2015-08-20 15:14:06 -070054 mType = Type::RoundRect;
Chris Craikb49f4462014-03-20 12:44:20 -070055 mBounds.set(left, top, right, bottom);
56 mRadius = radius;
Chris Craik40de9f22015-07-29 12:51:41 -070057
58 // update mPath to reflect new outline
Chris Craikb49f4462014-03-20 12:44:20 -070059 mPath.reset();
Chris Craik40de9f22015-07-29 12:51:41 -070060 if (MathUtils::isPositive(radius)) {
61 mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom),
62 radius, radius);
63 } else {
64 mPath.addRect(left, top, right, bottom);
65 }
Chris Craikb49f4462014-03-20 12:44:20 -070066 }
67
Chris Craik77b5cad2014-07-30 18:23:07 -070068 void setConvexPath(const SkPath* outline, float alpha) {
Chris Craikb49f4462014-03-20 12:44:20 -070069 if (!outline) {
70 setEmpty();
71 return;
72 }
Chris Craikb9ce116d2015-08-20 15:14:06 -070073 mType = Type::ConvexPath;
Chris Craikb49f4462014-03-20 12:44:20 -070074 mPath = *outline;
75 mBounds.set(outline->getBounds());
Chris Craik77b5cad2014-07-30 18:23:07 -070076 mAlpha = alpha;
Chris Craikb49f4462014-03-20 12:44:20 -070077 }
78
Chris Craik06451282014-07-21 10:25:54 -070079 void setEmpty() {
Chris Craikb9ce116d2015-08-20 15:14:06 -070080 mType = Type::Empty;
Chris Craik06451282014-07-21 10:25:54 -070081 mPath.reset();
Chris Craik77b5cad2014-07-30 18:23:07 -070082 mAlpha = 0.0f;
Chris Craik61317322014-05-21 13:03:52 -070083 }
84
Chris Craik06451282014-07-21 10:25:54 -070085 void setNone() {
Chris Craikb9ce116d2015-08-20 15:14:06 -070086 mType = Type::None;
Chris Craikb49f4462014-03-20 12:44:20 -070087 mPath.reset();
Chris Craik77b5cad2014-07-30 18:23:07 -070088 mAlpha = 0.0f;
Chris Craikb49f4462014-03-20 12:44:20 -070089 }
90
Chris Craik06451282014-07-21 10:25:54 -070091 bool isEmpty() const {
Chris Craikb9ce116d2015-08-20 15:14:06 -070092 return mType == Type::Empty;
Chris Craik06451282014-07-21 10:25:54 -070093 }
94
Chris Craik77b5cad2014-07-30 18:23:07 -070095 float getAlpha() const {
96 return mAlpha;
97 }
98
Chris Craikb49f4462014-03-20 12:44:20 -070099 void setShouldClip(bool clip) {
100 mShouldClip = clip;
101 }
102
Chris Craikdeeda3d2014-05-05 19:09:33 -0700103 bool getShouldClip() const {
104 return mShouldClip;
105 }
106
Chris Craikb49f4462014-03-20 12:44:20 -0700107 bool willClip() const {
108 // only round rect outlines can be used for clipping
Chris Craikb9ce116d2015-08-20 15:14:06 -0700109 return mShouldClip && (mType == Type::RoundRect);
Chris Craikb49f4462014-03-20 12:44:20 -0700110 }
111
Chris Craikb60d3e72015-06-25 17:15:16 -0700112 bool willRoundRectClip() const {
113 // only round rect outlines can be used for clipping
114 return willClip() && MathUtils::isPositive(mRadius);
115 }
116
Chris Craikdeeda3d2014-05-05 19:09:33 -0700117 bool getAsRoundRect(Rect* outRect, float* outRadius) const {
Chris Craikb9ce116d2015-08-20 15:14:06 -0700118 if (mType == Type::RoundRect) {
Chris Craikdeeda3d2014-05-05 19:09:33 -0700119 outRect->set(mBounds);
120 *outRadius = mRadius;
121 return true;
122 }
123 return false;
124 }
125
John Reckd0a0b2a2014-03-20 16:28:56 -0700126 const SkPath* getPath() const {
Chris Craikb9ce116d2015-08-20 15:14:06 -0700127 if (mType == Type::None || mType == Type::Empty) return nullptr;
Chris Craikb49f4462014-03-20 12:44:20 -0700128
129 return &mPath;
130 }
131
John Recke248bd12015-08-05 13:53:53 -0700132 Type getType() const {
133 return mType;
134 }
Chris Craikb49f4462014-03-20 12:44:20 -0700135
John Recke248bd12015-08-05 13:53:53 -0700136 const Rect& getBounds() const {
137 return mBounds;
138 }
139
140 float getRadius() const {
141 return mRadius;
142 }
143
144private:
Chris Craikb49f4462014-03-20 12:44:20 -0700145 bool mShouldClip;
Chris Craikb9ce116d2015-08-20 15:14:06 -0700146 Type mType;
Chris Craikb49f4462014-03-20 12:44:20 -0700147 Rect mBounds;
148 float mRadius;
Chris Craik77b5cad2014-07-30 18:23:07 -0700149 float mAlpha;
Chris Craikb49f4462014-03-20 12:44:20 -0700150 SkPath mPath;
151};
152
153} /* namespace uirenderer */
154} /* namespace android */
155
156#endif /* OUTLINE_H */