blob: 2eb2c7c7e29925aec7fe10e1a6e34dff5b0bdc24 [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:
Leon Scroggins IIIa49beaa2020-01-30 15:34:13 -050029 enum class Type { None = 0, Empty = 1, Path = 2, RoundRect = 3 };
John Recke248bd12015-08-05 13:53:53 -070030
John Reck1bcacfd2017-11-03 10:12:19 -070031 Outline() : mShouldClip(false), mType(Type::None), mRadius(0), mAlpha(0.0f) {}
Chris Craikb49f4462014-03-20 12:44:20 -070032
Chris Craik77b5cad2014-07-30 18:23:07 -070033 void setRoundRect(int left, int top, int right, int bottom, float radius, float alpha) {
Chris Craik40de9f22015-07-29 12:51:41 -070034 mAlpha = alpha;
John Reck1bcacfd2017-11-03 10:12:19 -070035 if (mType == Type::RoundRect && left == mBounds.left && right == mBounds.right &&
36 top == mBounds.top && bottom == mBounds.bottom && radius == mRadius) {
Chris Craik40de9f22015-07-29 12:51:41 -070037 // nothing to change, don't do any work
38 return;
39 }
40
Chris Craikb9ce116d2015-08-20 15:14:06 -070041 mType = Type::RoundRect;
Chris Craikb49f4462014-03-20 12:44:20 -070042 mBounds.set(left, top, right, bottom);
43 mRadius = radius;
Chris Craik40de9f22015-07-29 12:51:41 -070044
Stan Ilievf5638332017-12-08 11:32:12 -050045 // Reuse memory if previous outline was the same shape (rect or round rect).
John Recke170fb62018-05-07 08:12:07 -070046 if (mPath.countVerbs() > 10) {
Stan Ilievf5638332017-12-08 11:32:12 -050047 mPath.reset();
48 } else {
49 mPath.rewind();
50 }
51
Chris Craik40de9f22015-07-29 12:51:41 -070052 // update mPath to reflect new outline
Chris Craik40de9f22015-07-29 12:51:41 -070053 if (MathUtils::isPositive(radius)) {
John Reck1bcacfd2017-11-03 10:12:19 -070054 mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom), radius, radius);
Chris Craik40de9f22015-07-29 12:51:41 -070055 } else {
56 mPath.addRect(left, top, right, bottom);
57 }
Chris Craikb49f4462014-03-20 12:44:20 -070058 }
59
Leon Scroggins IIIa49beaa2020-01-30 15:34:13 -050060 void setPath(const SkPath* outline, float alpha) {
Chris Craikb49f4462014-03-20 12:44:20 -070061 if (!outline) {
62 setEmpty();
63 return;
64 }
Leon Scroggins IIIa49beaa2020-01-30 15:34:13 -050065 mType = Type::Path;
Chris Craikb49f4462014-03-20 12:44:20 -070066 mPath = *outline;
67 mBounds.set(outline->getBounds());
Chris Craik77b5cad2014-07-30 18:23:07 -070068 mAlpha = alpha;
Chris Craikb49f4462014-03-20 12:44:20 -070069 }
70
Chris Craik06451282014-07-21 10:25:54 -070071 void setEmpty() {
Chris Craikb9ce116d2015-08-20 15:14:06 -070072 mType = Type::Empty;
Chris Craik06451282014-07-21 10:25:54 -070073 mPath.reset();
Chris Craik77b5cad2014-07-30 18:23:07 -070074 mAlpha = 0.0f;
Chris Craik61317322014-05-21 13:03:52 -070075 }
76
Chris Craik06451282014-07-21 10:25:54 -070077 void setNone() {
Chris Craikb9ce116d2015-08-20 15:14:06 -070078 mType = Type::None;
Chris Craikb49f4462014-03-20 12:44:20 -070079 mPath.reset();
Chris Craik77b5cad2014-07-30 18:23:07 -070080 mAlpha = 0.0f;
Chris Craikb49f4462014-03-20 12:44:20 -070081 }
82
John Reck1bcacfd2017-11-03 10:12:19 -070083 bool isEmpty() const { return mType == Type::Empty; }
Chris Craik06451282014-07-21 10:25:54 -070084
John Reck1bcacfd2017-11-03 10:12:19 -070085 float getAlpha() const { return mAlpha; }
Chris Craik77b5cad2014-07-30 18:23:07 -070086
John Reck1bcacfd2017-11-03 10:12:19 -070087 void setShouldClip(bool clip) { mShouldClip = clip; }
Chris Craikb49f4462014-03-20 12:44:20 -070088
John Reck1bcacfd2017-11-03 10:12:19 -070089 bool getShouldClip() const { return mShouldClip; }
Chris Craikdeeda3d2014-05-05 19:09:33 -070090
Chris Craikb49f4462014-03-20 12:44:20 -070091 bool willClip() const {
92 // only round rect outlines can be used for clipping
Chris Craikb9ce116d2015-08-20 15:14:06 -070093 return mShouldClip && (mType == Type::RoundRect);
Chris Craikb49f4462014-03-20 12:44:20 -070094 }
95
Chris Craikb60d3e72015-06-25 17:15:16 -070096 bool willRoundRectClip() const {
97 // only round rect outlines can be used for clipping
98 return willClip() && MathUtils::isPositive(mRadius);
99 }
100
Chris Craikdeeda3d2014-05-05 19:09:33 -0700101 bool getAsRoundRect(Rect* outRect, float* outRadius) const {
Chris Craikb9ce116d2015-08-20 15:14:06 -0700102 if (mType == Type::RoundRect) {
Chris Craikdeeda3d2014-05-05 19:09:33 -0700103 outRect->set(mBounds);
104 *outRadius = mRadius;
105 return true;
106 }
107 return false;
108 }
109
John Reckd0a0b2a2014-03-20 16:28:56 -0700110 const SkPath* getPath() const {
Chris Craikb9ce116d2015-08-20 15:14:06 -0700111 if (mType == Type::None || mType == Type::Empty) return nullptr;
Chris Craikb49f4462014-03-20 12:44:20 -0700112
113 return &mPath;
114 }
115
John Reck1bcacfd2017-11-03 10:12:19 -0700116 Type getType() const { return mType; }
Chris Craikb49f4462014-03-20 12:44:20 -0700117
John Reck1bcacfd2017-11-03 10:12:19 -0700118 const Rect& getBounds() const { return mBounds; }
John Recke248bd12015-08-05 13:53:53 -0700119
John Reck1bcacfd2017-11-03 10:12:19 -0700120 float getRadius() const { return mRadius; }
John Recke248bd12015-08-05 13:53:53 -0700121
122private:
Chris Craikb49f4462014-03-20 12:44:20 -0700123 bool mShouldClip;
Chris Craikb9ce116d2015-08-20 15:14:06 -0700124 Type mType;
Chris Craikb49f4462014-03-20 12:44:20 -0700125 Rect mBounds;
126 float mRadius;
Chris Craik77b5cad2014-07-30 18:23:07 -0700127 float mAlpha;
Chris Craikb49f4462014-03-20 12:44:20 -0700128 SkPath mPath;
129};
130
131} /* namespace uirenderer */
132} /* namespace android */
133
134#endif /* OUTLINE_H */