ClipArea.h revision a2a70723b8cbda4354d23f901f995623e819012c
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 void 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 { 83private: 84 enum class Mode { 85 Rectangle, 86 Region, 87 RectangleList 88 }; 89 90public: 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); 101 void clipRectWithTransform(const Rect& r, const mat4* transform, 102 SkRegion::Op op); 103 void clipRegion(const SkRegion& region, SkRegion::Op op); 104 void clipPathWithTransform(const SkPath& path, const mat4* transform, 105 SkRegion::Op op); 106 107 const Rect& getClipRect() const { 108 return mClipRect; 109 } 110 111 const SkRegion& getClipRegion() const { 112 return mClipRegion; 113 } 114 115 const RectangleList& getRectangleList() const { 116 return mRectangleList; 117 } 118 119 bool isRegion() const { 120 return Mode::Region == mMode; 121 } 122 123 bool isSimple() const { 124 return mMode == Mode::Rectangle; 125 } 126 127 bool isRectangleList() const { 128 return mMode == Mode::RectangleList; 129 } 130 131private: 132 void enterRectangleMode(); 133 void rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op); 134 135 void enterRectangleListMode(); 136 void rectangleListModeClipRectWithTransform(const Rect& r, 137 const mat4* transform, SkRegion::Op op); 138 139 void enterRegionModeFromRectangleMode(); 140 void enterRegionModeFromRectangleListMode(); 141 void enterRegionMode(); 142 void regionModeClipRectWithTransform(const Rect& r, const mat4* transform, 143 SkRegion::Op op); 144 145 void ensureClipRegion(); 146 void onClipRegionUpdated(); 147 148 SkRegion createViewportRegion() { 149 return SkRegion(mViewportBounds.toSkIRect()); 150 } 151 152 void regionFromPath(const SkPath& path, SkRegion& pathAsRegion) { 153 // TODO: this should not mask every path to the viewport - this makes it impossible to use 154 // paths to clip to larger areas (which is valid e.g. with SkRegion::kReplace_Op) 155 pathAsRegion.setPath(path, createViewportRegion()); 156 } 157 158 Mode mMode; 159 Rect mViewportBounds; 160 Rect mClipRect; 161 SkRegion mClipRegion; 162 RectangleList mRectangleList; 163}; 164 165} /* namespace uirenderer */ 166} /* namespace android */ 167 168#endif /* CLIPAREA_H_ */ 169