ClipArea.h revision 8ce8f3f4d68a7750bc02b5254ebbd8658281e675
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 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 { 83public: 84 ClipArea(); 85 86 void setViewportDimensions(int width, int height); 87 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 102 const Rect& getClipRect() const { 103 return mClipRect; 104 } 105 106 const SkRegion& getClipRegion() const { 107 return mClipRegion; 108 } 109 110 const RectangleList& getRectangleList() const { 111 return mRectangleList; 112 } 113 114 bool isRegion() const { 115 return kModeRegion == mMode; 116 } 117 118 bool isSimple() const { 119 return mMode == kModeRectangle; 120 } 121 122 bool isRectangleList() const { 123 return mMode == kModeRectangleList; 124 } 125 126private: 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 151 SkRegion createViewportRegion() { 152 return SkRegion(mViewportBounds.toSkIRect()); 153 } 154 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