Home | History | Annotate | Download | only in hwui
      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 
     24 namespace android {
     25 namespace uirenderer {
     26 
     27 class Outline {
     28 public:
     29     enum class Type {
     30         None = 0,
     31         Empty = 1,
     32         ConvexPath = 2,
     33         RoundRect = 3
     34     };
     35 
     36     Outline()
     37             : mShouldClip(false)
     38             , mType(Type::None)
     39             , mRadius(0)
     40             , mAlpha(0.0f) {}
     41 
     42     void setRoundRect(int left, int top, int right, int bottom, float radius, float alpha) {
     43         mAlpha = alpha;
     44         if (mType == Type::RoundRect
     45                 && 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 
     54         mType = Type::RoundRect;
     55         mBounds.set(left, top, right, bottom);
     56         mRadius = radius;
     57 
     58         // update mPath to reflect new outline
     59         mPath.reset();
     60         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         }
     66     }
     67 
     68     void setConvexPath(const SkPath* outline, float alpha) {
     69         if (!outline) {
     70             setEmpty();
     71             return;
     72         }
     73         mType = Type::ConvexPath;
     74         mPath = *outline;
     75         mBounds.set(outline->getBounds());
     76         mAlpha = alpha;
     77     }
     78 
     79     void setEmpty() {
     80         mType = Type::Empty;
     81         mPath.reset();
     82         mAlpha = 0.0f;
     83     }
     84 
     85     void setNone() {
     86         mType = Type::None;
     87         mPath.reset();
     88         mAlpha = 0.0f;
     89     }
     90 
     91     bool isEmpty() const {
     92         return mType == Type::Empty;
     93     }
     94 
     95     float getAlpha() const {
     96         return mAlpha;
     97     }
     98 
     99     void setShouldClip(bool clip) {
    100         mShouldClip = clip;
    101     }
    102 
    103     bool getShouldClip() const {
    104         return mShouldClip;
    105     }
    106 
    107     bool willClip() const {
    108         // only round rect outlines can be used for clipping
    109         return mShouldClip && (mType == Type::RoundRect);
    110     }
    111 
    112     bool willRoundRectClip() const {
    113         // only round rect outlines can be used for clipping
    114         return willClip() && MathUtils::isPositive(mRadius);
    115     }
    116 
    117     bool getAsRoundRect(Rect* outRect, float* outRadius) const {
    118         if (mType == Type::RoundRect) {
    119             outRect->set(mBounds);
    120             *outRadius = mRadius;
    121             return true;
    122         }
    123         return false;
    124     }
    125 
    126     const SkPath* getPath() const {
    127         if (mType == Type::None || mType == Type::Empty) return nullptr;
    128 
    129         return &mPath;
    130     }
    131 
    132     Type getType() const {
    133         return mType;
    134     }
    135 
    136     const Rect& getBounds() const {
    137         return mBounds;
    138     }
    139 
    140     float getRadius() const {
    141         return mRadius;
    142     }
    143 
    144 private:
    145     bool mShouldClip;
    146     Type mType;
    147     Rect mBounds;
    148     float mRadius;
    149     float mAlpha;
    150     SkPath mPath;
    151 };
    152 
    153 } /* namespace uirenderer */
    154 } /* namespace android */
    155 
    156 #endif /* OUTLINE_H */
    157