ClipArea.h revision 487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8
1487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk/*
2487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * Copyright (C) 2015 The Android Open Source Project
3487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk *
4487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * Licensed under the Apache License, Version 2.0 (the "License");
5487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * you may not use this file except in compliance with the License.
6487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * You may obtain a copy of the License at
7487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk *
8487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk *      http://www.apache.org/licenses/LICENSE-2.0
9487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk *
10487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * Unless required by applicable law or agreed to in writing, software
11487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * distributed under the License is distributed on an "AS IS" BASIS,
12487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * See the License for the specific language governing permissions and
14487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk * limitations under the License.
15487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk */
16487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#ifndef CLIPAREA_H
17487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#define CLIPAREA_H
18487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
19487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include <SkRegion.h>
20487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
21487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include "Matrix.h"
22487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include "Rect.h"
23487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#include "utils/Pair.h"
24487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
25487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuknamespace android {
26487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuknamespace uirenderer {
27487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
28487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob TsukRect transformAndCalculateBounds(const Rect& r, const Matrix4& transform);
29487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
30487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukclass TransformedRectangle {
31487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukpublic:
32487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    TransformedRectangle();
33487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    TransformedRectangle(const Rect& bounds, const Matrix4& transform);
34487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
35487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool canSimplyIntersectWith(const TransformedRectangle& other) const;
36487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool intersectWith(const TransformedRectangle& other);
37487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
38487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool isEmpty() const;
39487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
40487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    const Rect& getBounds() const {
41487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return mBounds;
42487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
43487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
44487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    Rect transformedBounds() const {
45487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        Rect transformedBounds(transformAndCalculateBounds(mBounds, mTransform));
46487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return transformedBounds;
47487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
48487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
49487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    const Matrix4& getTransform() const {
50487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return mTransform;
51487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
52487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
53487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukprivate:
54487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    Rect mBounds;
55487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    Matrix4 mTransform;
56487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk};
57487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
58487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukclass RectangleList {
59487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukpublic:
60487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    RectangleList();
61487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
62487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool isEmpty() const;
63487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    int getTransformedRectanglesCount() const;
64487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    const TransformedRectangle& getTransformedRectangle(int i) const;
65487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
66487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void setEmpty();
67487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void set(const Rect& bounds, const Matrix4& transform);
68487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool intersectWith(const Rect& bounds, const Matrix4& transform);
69487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
70487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    SkRegion convertToRegion(const SkRegion& clip) const;
71487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    Rect calculateBounds() const;
72487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
73487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukprivate:
74487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    enum {
75487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        kMaxTransformedRectangles = 5
76487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    };
77487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
78487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    int mTransformedRectanglesCount;
79487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    TransformedRectangle mTransformedRectangles[kMaxTransformedRectangles];
80487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk};
81487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
82487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukclass ClipArea {
83487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukpublic:
84487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    ClipArea();
85487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
86487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void setViewportDimensions(int width, int height);
87487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
88487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool isEmpty() const {
89487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return mClipRect.isEmpty();
90487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
91487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
92487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void setEmpty();
93487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void setClip(float left, float top, float right, float bottom);
94487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool clipRectWithTransform(float left, float top, float right, float bottom,
95487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            const mat4* transform, SkRegion::Op op = SkRegion::kIntersect_Op);
96487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool clipRectWithTransform(const Rect& r, const mat4* transform,
97487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            SkRegion::Op op = SkRegion::kIntersect_Op);
98487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool clipRegion(const SkRegion& region, SkRegion::Op op = SkRegion::kIntersect_Op);
99487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool clipPathWithTransform(const SkPath& path, const mat4* transform,
100487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            SkRegion::Op op);
101487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
102487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    const Rect& getClipRect() const {
103487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return mClipRect;
104487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
105487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
106487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    const SkRegion& getClipRegion() const {
107487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return mClipRegion;
108487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
109487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
110487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    const RectangleList& getRectangleList() const {
111487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return mRectangleList;
112487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
113487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
114487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool isRegion() const {
115487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return kModeRegion == mMode;
116487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
117487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
118487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool isSimple() const {
119487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return mMode == kModeRectangle;
120487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
121487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
122487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool isRectangleList() const {
123487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return mMode == kModeRectangleList;
124487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
125487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
126487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukprivate:
127487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void enterRectangleMode();
128487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
129487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool rectangleModeClipRectWithTransform(float left, float top, float right,
130487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            float bottom, const mat4* transform, SkRegion::Op op);
131487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
132487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void enterRectangleListMode();
133487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool rectangleListModeClipRectWithTransform(float left, float top,
134487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            float right, float bottom, const mat4* transform, SkRegion::Op op);
135487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool rectangleListModeClipRectWithTransform(const Rect& r,
136487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            const mat4* transform, SkRegion::Op op);
137487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
138487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void enterRegionModeFromRectangleMode();
139487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void enterRegionModeFromRectangleListMode();
140487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void enterRegionMode();
141487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool regionModeClipRectWithTransform(const Rect& r, const mat4* transform,
142487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            SkRegion::Op op);
143487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool regionModeClipRectWithTransform(float left, float top, float right,
144487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            float bottom, const mat4* transform, SkRegion::Op op);
145487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
146487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void ensureClipRegion();
147487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void setClipRectToRegionBounds();
148487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    bool clipRegionOp(float left, float top, float right, float bottom,
149487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk            SkRegion::Op op);
150487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
151487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    SkRegion createViewportRegion() {
152487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        return SkRegion(mViewportBounds.toSkIRect());
153487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
154487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
155487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    void regionFromPath(const SkPath& path, SkRegion& pathAsRegion) {
156487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        pathAsRegion.setPath(path, createViewportRegion());
157487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    }
158487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
159487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    enum Mode {
160487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        kModeRectangle,
161487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        kModeRegion,
162487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk        kModeRectangleList
163487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    };
164487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
165487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    Mode mMode;
166487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    Rect mViewportBounds;
167487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    Rect mClipRect;
168487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    SkRegion mClipRegion;
169487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    RectangleList mRectangleList;
170487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk};
171487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
172487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} /* namespace uirenderer */
173487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} /* namespace android */
174487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk
175487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#endif /* CLIPAREA_H_ */
176