ClipArea.h revision ac02eb9035a13a3d09c2def9ed63d04225eb2509
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; 36ac02eb9035a13a3d09c2def9ed63d04225eb2509Chris Craik void 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 { 834d3e704b04c6abd7995df640d12662b0271f6c7bChris Craikprivate: 844d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik enum class Mode { 854d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik Rectangle, 864d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik Region, 874d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik RectangleList 884d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik }; 894d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik 90487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukpublic: 91487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk ClipArea(); 92487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 93487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void setViewportDimensions(int width, int height); 94487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 95487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk bool isEmpty() const { 96487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return mClipRect.isEmpty(); 97487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 98487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 99487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void setEmpty(); 100487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void setClip(float left, float top, float right, float bottom); 1014d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void clipRectWithTransform(float left, float top, float right, float bottom, 1024d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik const mat4* transform, SkRegion::Op op); 1034d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void clipRectWithTransform(const Rect& r, const mat4* transform, 1044d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik SkRegion::Op op); 1054d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void clipRegion(const SkRegion& region, SkRegion::Op op); 1064d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void clipPathWithTransform(const SkPath& path, const mat4* transform, 107487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkRegion::Op op); 108487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 109487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk const Rect& getClipRect() const { 110487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return mClipRect; 111487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 112487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 113487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk const SkRegion& getClipRegion() const { 114487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return mClipRegion; 115487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 116487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 117487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk const RectangleList& getRectangleList() const { 118487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return mRectangleList; 119487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 120487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 121487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk bool isRegion() const { 1224d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik return Mode::Region == mMode; 123487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 124487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 125487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk bool isSimple() const { 1264d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik return mMode == Mode::Rectangle; 127487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 128487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 129487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk bool isRectangleList() const { 1304d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik return mMode == Mode::RectangleList; 131487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 132487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 133487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukprivate: 134487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void enterRectangleMode(); 1354d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op); 1364d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void rectangleModeClipRectWithTransform(float left, float top, float right, 137487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk float bottom, const mat4* transform, SkRegion::Op op); 138487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 139487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void enterRectangleListMode(); 1404d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void rectangleListModeClipRectWithTransform(float left, float top, 141487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk float right, float bottom, const mat4* transform, SkRegion::Op op); 1424d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void rectangleListModeClipRectWithTransform(const Rect& r, 143487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk const mat4* transform, SkRegion::Op op); 144487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 145487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void enterRegionModeFromRectangleMode(); 146487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void enterRegionModeFromRectangleListMode(); 147487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void enterRegionMode(); 1484d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void regionModeClipRectWithTransform(const Rect& r, const mat4* transform, 149487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkRegion::Op op); 1504d3e704b04c6abd7995df640d12662b0271f6c7bChris Craik void regionModeClipRectWithTransform(float left, float top, float right, 151487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk float bottom, const mat4* transform, SkRegion::Op op); 152487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 153487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void ensureClipRegion(); 154e30b53cec5eb6eaa5d24231feb3207b917c1baabTom Hudson void onClipRegionUpdated(); 155487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 156487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkRegion createViewportRegion() { 157487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk return SkRegion(mViewportBounds.toSkIRect()); 158487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 159487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 160487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk void regionFromPath(const SkPath& path, SkRegion& pathAsRegion) { 1618ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik // TODO: this should not mask every path to the viewport - this makes it impossible to use 1628ce8f3f4d68a7750bc02b5254ebbd8658281e675Chris Craik // paths to clip to larger areas (which is valid e.g. with SkRegion::kReplace_Op) 163487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk pathAsRegion.setPath(path, createViewportRegion()); 164487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 165487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 166487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Mode mMode; 167487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect mViewportBounds; 168487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk Rect mClipRect; 169487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk SkRegion mClipRegion; 170487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk RectangleList mRectangleList; 171487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk}; 172487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 173487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} /* namespace uirenderer */ 174487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk} /* namespace android */ 175487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk 176487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk#endif /* CLIPAREA_H_ */ 177