1 /* 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 25 namespace android { 26 namespace uirenderer { 27 28 Rect transformAndCalculateBounds(const Rect& r, const Matrix4& transform); 29 30 class TransformedRectangle { 31 public: 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 getBounds()40 const Rect& getBounds() const { 41 return mBounds; 42 } 43 transformedBounds()44 Rect transformedBounds() const { 45 Rect transformedBounds(transformAndCalculateBounds(mBounds, mTransform)); 46 return transformedBounds; 47 } 48 getTransform()49 const Matrix4& getTransform() const { 50 return mTransform; 51 } 52 53 private: 54 Rect mBounds; 55 Matrix4 mTransform; 56 }; 57 58 class RectangleList { 59 public: 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 73 private: 74 enum { 75 kMaxTransformedRectangles = 5 76 }; 77 78 int mTransformedRectanglesCount; 79 TransformedRectangle mTransformedRectangles[kMaxTransformedRectangles]; 80 }; 81 82 class ClipArea { 83 public: 84 ClipArea(); 85 86 void setViewportDimensions(int width, int height); 87 isEmpty()88 bool isEmpty() const { 89 return mClipRect.isEmpty(); 90 } 91 92 void setEmpty(); 93 void setClip(float left, float top, float right, float bottom); 94 bool clipRectWithTransform(float left, float top, float right, float bottom, 95 const mat4* transform, SkRegion::Op op = SkRegion::kIntersect_Op); 96 bool clipRectWithTransform(const Rect& r, const mat4* transform, 97 SkRegion::Op op = SkRegion::kIntersect_Op); 98 bool clipRegion(const SkRegion& region, SkRegion::Op op = SkRegion::kIntersect_Op); 99 bool clipPathWithTransform(const SkPath& path, const mat4* transform, 100 SkRegion::Op op); 101 getClipRect()102 const Rect& getClipRect() const { 103 return mClipRect; 104 } 105 getClipRegion()106 const SkRegion& getClipRegion() const { 107 return mClipRegion; 108 } 109 getRectangleList()110 const RectangleList& getRectangleList() const { 111 return mRectangleList; 112 } 113 isRegion()114 bool isRegion() const { 115 return kModeRegion == mMode; 116 } 117 isSimple()118 bool isSimple() const { 119 return mMode == kModeRectangle; 120 } 121 isRectangleList()122 bool isRectangleList() const { 123 return mMode == kModeRectangleList; 124 } 125 126 private: 127 void enterRectangleMode(); 128 bool rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op); 129 bool rectangleModeClipRectWithTransform(float left, float top, float right, 130 float bottom, const mat4* transform, SkRegion::Op op); 131 132 void enterRectangleListMode(); 133 bool rectangleListModeClipRectWithTransform(float left, float top, 134 float right, float bottom, const mat4* transform, SkRegion::Op op); 135 bool rectangleListModeClipRectWithTransform(const Rect& r, 136 const mat4* transform, SkRegion::Op op); 137 138 void enterRegionModeFromRectangleMode(); 139 void enterRegionModeFromRectangleListMode(); 140 void enterRegionMode(); 141 bool regionModeClipRectWithTransform(const Rect& r, const mat4* transform, 142 SkRegion::Op op); 143 bool regionModeClipRectWithTransform(float left, float top, float right, 144 float bottom, const mat4* transform, SkRegion::Op op); 145 146 void ensureClipRegion(); 147 void onClipRegionUpdated(); 148 bool clipRegionOp(float left, float top, float right, float bottom, 149 SkRegion::Op op); 150 createViewportRegion()151 SkRegion createViewportRegion() { 152 return SkRegion(mViewportBounds.toSkIRect()); 153 } 154 regionFromPath(const SkPath & path,SkRegion & pathAsRegion)155 void regionFromPath(const SkPath& path, SkRegion& pathAsRegion) { 156 // TODO: this should not mask every path to the viewport - this makes it impossible to use 157 // paths to clip to larger areas (which is valid e.g. with SkRegion::kReplace_Op) 158 pathAsRegion.setPath(path, createViewportRegion()); 159 } 160 161 enum Mode { 162 kModeRectangle, 163 kModeRegion, 164 kModeRectangleList 165 }; 166 167 Mode mMode; 168 Rect mViewportBounds; 169 Rect mClipRect; 170 SkRegion mClipRegion; 171 RectangleList mRectangleList; 172 }; 173 174 } /* namespace uirenderer */ 175 } /* namespace android */ 176 177 #endif /* CLIPAREA_H_ */ 178