blob: 38fefe5ab097b0f6322e2c15d05964b4bb2f61df [file] [log] [blame]
Rob Tsuk487a92c2015-01-06 13:22:54 -08001/*
2 * Copyright (C) 2015 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 CLIPAREA_H
17#define CLIPAREA_H
18
19#include <SkRegion.h>
20
21#include "Matrix.h"
22#include "Rect.h"
23#include "utils/Pair.h"
24
25namespace android {
26namespace uirenderer {
27
28Rect transformAndCalculateBounds(const Rect& r, const Matrix4& transform);
29
30class TransformedRectangle {
31public:
32 TransformedRectangle();
33 TransformedRectangle(const Rect& bounds, const Matrix4& transform);
34
35 bool canSimplyIntersectWith(const TransformedRectangle& other) const;
36 bool intersectWith(const TransformedRectangle& other);
37
38 bool isEmpty() const;
39
40 const Rect& getBounds() const {
41 return mBounds;
42 }
43
44 Rect transformedBounds() const {
45 Rect transformedBounds(transformAndCalculateBounds(mBounds, mTransform));
46 return transformedBounds;
47 }
48
49 const Matrix4& getTransform() const {
50 return mTransform;
51 }
52
53private:
54 Rect mBounds;
55 Matrix4 mTransform;
56};
57
58class RectangleList {
59public:
60 RectangleList();
61
62 bool isEmpty() const;
63 int getTransformedRectanglesCount() const;
64 const TransformedRectangle& getTransformedRectangle(int i) const;
65
66 void setEmpty();
67 void set(const Rect& bounds, const Matrix4& transform);
68 bool intersectWith(const Rect& bounds, const Matrix4& transform);
69
70 SkRegion convertToRegion(const SkRegion& clip) const;
71 Rect calculateBounds() const;
72
73private:
74 enum {
75 kMaxTransformedRectangles = 5
76 };
77
78 int mTransformedRectanglesCount;
79 TransformedRectangle mTransformedRectangles[kMaxTransformedRectangles];
80};
81
82class ClipArea {
Chris Craik4d3e7042015-08-20 12:54:25 -070083private:
84 enum class Mode {
85 Rectangle,
86 Region,
87 RectangleList
88 };
89
Rob Tsuk487a92c2015-01-06 13:22:54 -080090public:
91 ClipArea();
92
93 void setViewportDimensions(int width, int height);
94
95 bool isEmpty() const {
96 return mClipRect.isEmpty();
97 }
98
99 void setEmpty();
100 void setClip(float left, float top, float right, float bottom);
Chris Craik4d3e7042015-08-20 12:54:25 -0700101 void clipRectWithTransform(float left, float top, float right, float bottom,
102 const mat4* transform, SkRegion::Op op);
103 void clipRectWithTransform(const Rect& r, const mat4* transform,
104 SkRegion::Op op);
105 void clipRegion(const SkRegion& region, SkRegion::Op op);
106 void clipPathWithTransform(const SkPath& path, const mat4* transform,
Rob Tsuk487a92c2015-01-06 13:22:54 -0800107 SkRegion::Op op);
108
109 const Rect& getClipRect() const {
110 return mClipRect;
111 }
112
113 const SkRegion& getClipRegion() const {
114 return mClipRegion;
115 }
116
117 const RectangleList& getRectangleList() const {
118 return mRectangleList;
119 }
120
121 bool isRegion() const {
Chris Craik4d3e7042015-08-20 12:54:25 -0700122 return Mode::Region == mMode;
Rob Tsuk487a92c2015-01-06 13:22:54 -0800123 }
124
125 bool isSimple() const {
Chris Craik4d3e7042015-08-20 12:54:25 -0700126 return mMode == Mode::Rectangle;
Rob Tsuk487a92c2015-01-06 13:22:54 -0800127 }
128
129 bool isRectangleList() const {
Chris Craik4d3e7042015-08-20 12:54:25 -0700130 return mMode == Mode::RectangleList;
Rob Tsuk487a92c2015-01-06 13:22:54 -0800131 }
132
133private:
134 void enterRectangleMode();
Chris Craik4d3e7042015-08-20 12:54:25 -0700135 void rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
136 void rectangleModeClipRectWithTransform(float left, float top, float right,
Rob Tsuk487a92c2015-01-06 13:22:54 -0800137 float bottom, const mat4* transform, SkRegion::Op op);
138
139 void enterRectangleListMode();
Chris Craik4d3e7042015-08-20 12:54:25 -0700140 void rectangleListModeClipRectWithTransform(float left, float top,
Rob Tsuk487a92c2015-01-06 13:22:54 -0800141 float right, float bottom, const mat4* transform, SkRegion::Op op);
Chris Craik4d3e7042015-08-20 12:54:25 -0700142 void rectangleListModeClipRectWithTransform(const Rect& r,
Rob Tsuk487a92c2015-01-06 13:22:54 -0800143 const mat4* transform, SkRegion::Op op);
144
145 void enterRegionModeFromRectangleMode();
146 void enterRegionModeFromRectangleListMode();
147 void enterRegionMode();
Chris Craik4d3e7042015-08-20 12:54:25 -0700148 void regionModeClipRectWithTransform(const Rect& r, const mat4* transform,
Rob Tsuk487a92c2015-01-06 13:22:54 -0800149 SkRegion::Op op);
Chris Craik4d3e7042015-08-20 12:54:25 -0700150 void regionModeClipRectWithTransform(float left, float top, float right,
Rob Tsuk487a92c2015-01-06 13:22:54 -0800151 float bottom, const mat4* transform, SkRegion::Op op);
152
153 void ensureClipRegion();
Tom Hudsone30b53c2015-03-30 15:59:02 -0400154 void onClipRegionUpdated();
Rob Tsuk487a92c2015-01-06 13:22:54 -0800155
156 SkRegion createViewportRegion() {
157 return SkRegion(mViewportBounds.toSkIRect());
158 }
159
160 void regionFromPath(const SkPath& path, SkRegion& pathAsRegion) {
Chris Craik8ce8f3f2015-07-16 13:07:45 -0700161 // TODO: this should not mask every path to the viewport - this makes it impossible to use
162 // paths to clip to larger areas (which is valid e.g. with SkRegion::kReplace_Op)
Rob Tsuk487a92c2015-01-06 13:22:54 -0800163 pathAsRegion.setPath(path, createViewportRegion());
164 }
165
Rob Tsuk487a92c2015-01-06 13:22:54 -0800166 Mode mMode;
167 Rect mViewportBounds;
168 Rect mClipRect;
169 SkRegion mClipRegion;
170 RectangleList mRectangleList;
171};
172
173} /* namespace uirenderer */
174} /* namespace android */
175
176#endif /* CLIPAREA_H_ */